HttpWebRequest failure with TLS

Discussion in 'ASP .Net Security' started by Sholto Douglas, Sep 23, 2005.

  1. I am using HttpWebRequest to access a WebLogic web servce. It is currently
    in a console app, but will be 'elevated' to a service.
    The code is pretty standard, but I get the dreaded WebException:
    The underlying connection was closed: Could not establish secure channel
    for SSL/TLS
    It uses 2-way SSL/TLS. I am adding the client certificate to the
    ClientCertificates property. I have added the server certificate to my
    CurrentUser store. The server has my (client) certificate. What more can I
    do, for heavens sake?
    The WebLogic log shows that we complete the first 3 stages of the handshake,
    namely up to here:

    *** ServerHelloDone
    HttpProcessor[8082][4], WRITE: TLSv1 Handshake, length = 4972
    HttpProcessor[8082][4], received EOFException: error
    HttpProcessor[8082][4], handling
    exception:javax.net.ssl.SSLHandshakeException: Remote host closed connection
    during handshake
    HttpProcessor[8082][4], SEND TLSv1 ALERT: fatal, description =
    unexpected_message
    HttpProcessor[8082][4], WRITE: TLSv1 Alert, length = 2
    ...
    ...

    At this point the client should send the client certificate to the server,
    but it doesn't.
    For what it's worth, here is the code:

    HttpWebRequest webRequest =
    (HttpWebRequest)WebRequest.Create(sUri);
    webRequest.Method = "POST";
    webRequest.KeepAlive = false;
    webRequest.ContentType = "text/xml";
    webRequest.ContentLength = in_sXml.Length;
    // Add the authentication certificates
    if (m_x509ClientCert != null)
    webRequest.ClientCertificates.Add(m_x509ClientCert);

    StreamWriter SW = new StreamWriter(webRequest.GetRequestStream());
    SW.Write(in_sXml);
    SW.Close();

    // Wait for response...
    HttpWebResponse webResponse =
    (HttpWebResponse)webRequest.GetResponse();

    It throws the exception at the webRequest.GetRequestStream() call.

    In the class constructor I have set the ServicePointManager.SecurityProtocol
    to
    SecurityProtocolType.Tls, and the CertificatePolicy to accept all
    certificates.

    Can anyone tell me what I have missed?
    --
    Thanks for any help,
    Sholto Douglas
    His Nerdship Pty Ltd
     
    Sholto Douglas, Sep 23, 2005
    #1
    1. Advertising

  2. This generally means that your client code doesn't have access to the
    private key for the certificate in question, although it could be an issue
    with certificate trust as well.

    Debugging these issues is notoriously difficult I'm afraid.

    The first thing I would do is make sure the certificate in question has a
    private key associated with it. Then, make sure you can navigate to the
    page in question with the browser and that IE will prompt you for the client
    certificate.

    After that, using regmon and filemon while the program is running is often
    very helpful for determining where Windows is looking for the private key
    file and who is getting denied access.

    There are also some kbase articles on this issue.

    Joe K.

    "Sholto Douglas" <> wrote in message
    news:...
    >I am using HttpWebRequest to access a WebLogic web servce. It is currently
    > in a console app, but will be 'elevated' to a service.
    > The code is pretty standard, but I get the dreaded WebException:
    > The underlying connection was closed: Could not establish secure channel
    > for SSL/TLS
    > It uses 2-way SSL/TLS. I am adding the client certificate to the
    > ClientCertificates property. I have added the server certificate to my
    > CurrentUser store. The server has my (client) certificate. What more can
    > I
    > do, for heavens sake?
    > The WebLogic log shows that we complete the first 3 stages of the
    > handshake,
    > namely up to here:
    >
    > *** ServerHelloDone
    > HttpProcessor[8082][4], WRITE: TLSv1 Handshake, length = 4972
    > HttpProcessor[8082][4], received EOFException: error
    > HttpProcessor[8082][4], handling
    > exception:javax.net.ssl.SSLHandshakeException: Remote host closed
    > connection
    > during handshake
    > HttpProcessor[8082][4], SEND TLSv1 ALERT: fatal, description =
    > unexpected_message
    > HttpProcessor[8082][4], WRITE: TLSv1 Alert, length = 2
    > ...
    > ...
    >
    > At this point the client should send the client certificate to the server,
    > but it doesn't.
    > For what it's worth, here is the code:
    >
    > HttpWebRequest webRequest =
    > (HttpWebRequest)WebRequest.Create(sUri);
    > webRequest.Method = "POST";
    > webRequest.KeepAlive = false;
    > webRequest.ContentType = "text/xml";
    > webRequest.ContentLength = in_sXml.Length;
    > // Add the authentication certificates
    > if (m_x509ClientCert != null)
    > webRequest.ClientCertificates.Add(m_x509ClientCert);
    >
    > StreamWriter SW = new StreamWriter(webRequest.GetRequestStream());
    > SW.Write(in_sXml);
    > SW.Close();
    >
    > // Wait for response...
    > HttpWebResponse webResponse =
    > (HttpWebResponse)webRequest.GetResponse();
    >
    > It throws the exception at the webRequest.GetRequestStream() call.
    >
    > In the class constructor I have set the
    > ServicePointManager.SecurityProtocol
    > to
    > SecurityProtocolType.Tls, and the CertificatePolicy to accept all
    > certificates.
    >
    > Can anyone tell me what I have missed?
    > --
    > Thanks for any help,
    > Sholto Douglas
    > His Nerdship Pty Ltd
     
    Joe Kaplan \(MVP - ADSI\), Sep 23, 2005
    #2
    1. Advertising

  3. Thanks for answering, Joe,

    > Debugging these issues is notoriously difficult I'm afraid.
    >

    Tell me about it..... What is annoying is that whatever the problem, I
    always get the same exception message. The .NET error messages should be
    more explicit.

    > This generally means that your client code doesn't have access to the
    > private key for the certificate in question, although it could be an issue
    > with certificate trust as well.
    >

    I put both keys (client and server) into the Personal 'folder' of the
    CurrentUser store. Do they need to be in the LocalMachine store? If so,
    which folder? Personal, Trusted People? I imagine the CurrentUser store
    would be less prone to permission problems, which is why I put them there.
    How can I be sure I do have the required access?

    > The first thing I would do is make sure the certificate in question has a
    > private key associated with it. Then, make sure you can navigate to the
    > page in question with the browser and that IE will prompt you for the client
    > certificate.
    >

    I am confident there is a private key, because I was asked if I wanted to
    export it (I didn't, of course!). I am actually going through a colleague's
    laptop with Tomcat installed, then to a proxy, before the actual web service.
    So I have never been able to bring up the page in IE (they aren't making it
    easy for me).

    Thanks again, Joe,
    Sholto Douglas
    His Nerdship Pty Ltd (Australia)


    "Joe Kaplan (MVP - ADSI)" wrote:

    > This generally means that your client code doesn't have access to the
    > private key for the certificate in question, although it could be an issue
    > with certificate trust as well.
    >
    > Debugging these issues is notoriously difficult I'm afraid.
    >
    > The first thing I would do is make sure the certificate in question has a
    > private key associated with it. Then, make sure you can navigate to the
    > page in question with the browser and that IE will prompt you for the client
    > certificate.
    >
    > After that, using regmon and filemon while the program is running is often
    > very helpful for determining where Windows is looking for the private key
    > file and who is getting denied access.
    >
    > There are also some kbase articles on this issue.
    >
    > Joe K.
     
    Sholto Douglas, Sep 24, 2005
    #3
  4. My guess is that you are going to want it in the machine store as the
    account your web service client is running under will eventually change to
    the service process' account, but it should work in either for the console
    app as your user profile will be loaded.

    The MMC snap-in will tell you for sure if the client certificate has a
    private key associated with it in the cert properties dialog. The client
    certificate should go in the personal store.

    You probably don't need the server's certificate on your machine at all as
    long as your machine trusts it.

    If you can't bring up the page in IE, that might mean that the underlying
    Wininet goo can't get to it either. Be careful with that as this might not
    be a client certificate issue at all.

    Another useful thing is to play with the schannel logging level to see
    detailed log messages on the certificate exchange stuff in the event log:
    http://support.microsoft.com/?id=260729

    Joe K.

    "Sholto Douglas" <> wrote in message
    news:...
    > Thanks for answering, Joe,
    >
    >> Debugging these issues is notoriously difficult I'm afraid.
    >>

    > Tell me about it..... What is annoying is that whatever the problem, I
    > always get the same exception message. The .NET error messages should be
    > more explicit.
    >
    >> This generally means that your client code doesn't have access to the
    >> private key for the certificate in question, although it could be an
    >> issue
    >> with certificate trust as well.
    >>

    > I put both keys (client and server) into the Personal 'folder' of the
    > CurrentUser store. Do they need to be in the LocalMachine store? If so,
    > which folder? Personal, Trusted People? I imagine the CurrentUser store
    > would be less prone to permission problems, which is why I put them there.
    > How can I be sure I do have the required access?
    >
    >> The first thing I would do is make sure the certificate in question has a
    >> private key associated with it. Then, make sure you can navigate to the
    >> page in question with the browser and that IE will prompt you for the
    >> client
    >> certificate.
    >>

    > I am confident there is a private key, because I was asked if I wanted to
    > export it (I didn't, of course!). I am actually going through a
    > colleague's
    > laptop with Tomcat installed, then to a proxy, before the actual web
    > service.
    > So I have never been able to bring up the page in IE (they aren't making
    > it
    > easy for me).
    >
    > Thanks again, Joe,
    > Sholto Douglas
    > His Nerdship Pty Ltd (Australia)
    >
    >
    > "Joe Kaplan (MVP - ADSI)" wrote:
    >
    >> This generally means that your client code doesn't have access to the
    >> private key for the certificate in question, although it could be an
    >> issue
    >> with certificate trust as well.
    >>
    >> Debugging these issues is notoriously difficult I'm afraid.
    >>
    >> The first thing I would do is make sure the certificate in question has a
    >> private key associated with it. Then, make sure you can navigate to the
    >> page in question with the browser and that IE will prompt you for the
    >> client
    >> certificate.
    >>
    >> After that, using regmon and filemon while the program is running is
    >> often
    >> very helpful for determining where Windows is looking for the private key
    >> file and who is getting denied access.
    >>
    >> There are also some kbase articles on this issue.
    >>
    >> Joe K.

    >
     
    Joe Kaplan \(MVP - ADSI\), Sep 24, 2005
    #4
  5. Hi Joe,
    Still no progress.... However I do have a couple of pointers.
    Firstly when I try to bring up the web service in IE, I just get "The page
    cannot be displayed". On the Tomcat server they get exactly the same log
    message as when it fails from my app, and it dies at the same point
    (ServerHelloDone). Apparently the server is waiting for a certificate, which
    it doesn't get (either from my app, or from IE). I get no message prompting
    me for a client certificate.
    I have added the client key to the Personal folders of both the Local
    Machine store, and the Current User one. As I said, there is definitely a
    private key because when I try to export the certificate (in MMC), it prompts
    me if I want to export the private key.
    I have also added the root certificate to the Trusted Root Certification
    Authority in both stores. As you said, given that it is a console app, it
    should always have access to the Current User store.

    I activated the SCHANNEL logging, setting the value to 7 (i.e everything).
    However I only got one (Information) line - it just said "Creating an SSL
    client credential." There were no error messages, suggesting it bombed out
    early.

    Finally to see if the problem was TLS related, I removed the code that
    forced a TLS handshake (so it would default to SSLv3). Still failed.

    I appreciate your help Joe. This whole business is making me look very
    incompetent!
    --
    Cheers,
    Sholto


    "Joe Kaplan (MVP - ADSI)" wrote:

    > My guess is that you are going to want it in the machine store as the
    > account your web service client is running under will eventually change to
    > the service process' account, but it should work in either for the console
    > app as your user profile will be loaded.
    >
    > The MMC snap-in will tell you for sure if the client certificate has a
    > private key associated with it in the cert properties dialog. The client
    > certificate should go in the personal store.
    >
    > You probably don't need the server's certificate on your machine at all as
    > long as your machine trusts it.
    >
    > If you can't bring up the page in IE, that might mean that the underlying
    > Wininet goo can't get to it either. Be careful with that as this might not
    > be a client certificate issue at all.
    >
    > Another useful thing is to play with the schannel logging level to see
    > detailed log messages on the certificate exchange stuff in the event log:
    > http://support.microsoft.com/?id=260729
    >
    > Joe K.
     
    Sholto Douglas, Sep 26, 2005
    #5
  6. Interesting. No Schannel error on the client credential creation? It
    sounds like it is actually creating the client certificate part of the
    handshake. Is it possible that the server side implementation doesn't
    properly trust the client certificate or there is a configuration issue on
    their side?

    I have no idea how to suggest to troubleshoot that as I only know IIS, but
    they probably use OpenSSL and I think it has some good logging facilities.

    Best of luck on this one...

    Joe K.

    "Sholto Douglas" <> wrote in message
    news:...
    > Hi Joe,
    > Still no progress.... However I do have a couple of pointers.
    > Firstly when I try to bring up the web service in IE, I just get "The page
    > cannot be displayed". On the Tomcat server they get exactly the same log
    > message as when it fails from my app, and it dies at the same point
    > (ServerHelloDone). Apparently the server is waiting for a certificate,
    > which
    > it doesn't get (either from my app, or from IE). I get no message
    > prompting
    > me for a client certificate.
    > I have added the client key to the Personal folders of both the Local
    > Machine store, and the Current User one. As I said, there is definitely a
    > private key because when I try to export the certificate (in MMC), it
    > prompts
    > me if I want to export the private key.
    > I have also added the root certificate to the Trusted Root Certification
    > Authority in both stores. As you said, given that it is a console app, it
    > should always have access to the Current User store.
    >
    > I activated the SCHANNEL logging, setting the value to 7 (i.e everything).
    > However I only got one (Information) line - it just said "Creating an SSL
    > client credential." There were no error messages, suggesting it bombed
    > out
    > early.
    >
    > Finally to see if the problem was TLS related, I removed the code that
    > forced a TLS handshake (so it would default to SSLv3). Still failed.
    >
    > I appreciate your help Joe. This whole business is making me look very
    > incompetent!
    > --
    > Cheers,
    > Sholto
    >
    >
    > "Joe Kaplan (MVP - ADSI)" wrote:
    >
    >> My guess is that you are going to want it in the machine store as the
    >> account your web service client is running under will eventually change
    >> to
    >> the service process' account, but it should work in either for the
    >> console
    >> app as your user profile will be loaded.
    >>
    >> The MMC snap-in will tell you for sure if the client certificate has a
    >> private key associated with it in the cert properties dialog. The client
    >> certificate should go in the personal store.
    >>
    >> You probably don't need the server's certificate on your machine at all
    >> as
    >> long as your machine trusts it.
    >>
    >> If you can't bring up the page in IE, that might mean that the underlying
    >> Wininet goo can't get to it either. Be careful with that as this might
    >> not
    >> be a client certificate issue at all.
    >>
    >> Another useful thing is to play with the schannel logging level to see
    >> detailed log messages on the certificate exchange stuff in the event log:
    >> http://support.microsoft.com/?id=260729
    >>
    >> Joe K.

    >
     
    Joe Kaplan \(MVP - ADSI\), Sep 26, 2005
    #6
  7. Sholto Douglas

    Peter Jakab Guest

    Hi Sholto,

    I already told you in an email, that we were in the same situation, and the
    problem was with the server certificate, that we used on the weblogic, re
    creating it with the keytool solved the problem.

    One more thing iwould like to add:

    In case you want to access the weblogic web service from a web application,
    for the process to have access to the client certificate, the client
    certificate must be placed into the LOCAL_MACHINE store, and the account,
    with whose identity the application pool of the app is running, must have
    access to the cert.

    If the app pool was running with NEtwork service identity, you should have
    to grant access to it using the

    C:\Program Files\Windows Resource Kits\Tools>winhttpcertcfg -g -a "NETWORK
    SERVICE" -s "pannongsm.hu" -c LOCAL_MACHINE\MY

    command (after downloading and installing the winhttpcertconfig tool from MS
    from

    http://www.microsoft.com/downloads/...ac-3409-40e9-8667-c748e422833f&displaylang=en

    and importing the client certificate to the LOCAL_MACHINE\Personal
    store.

    In case we imported the client cert to the current_user store of the service
    account, it worked fine until the first reboot of the server, after that the
    worker process couldn't access the cert stored in the users store.
    This is NOT mentioned in the MS Article...

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT13.asp

    On the other hand, this article is great, I think.

    Best regards

    Peter Jakab



    "Joe Kaplan (MVP - ADSI)" <> wrote
    in message news:...
    > Interesting. No Schannel error on the client credential creation? It
    > sounds like it is actually creating the client certificate part of the
    > handshake. Is it possible that the server side implementation doesn't
    > properly trust the client certificate or there is a configuration issue on
    > their side?
    >
    > I have no idea how to suggest to troubleshoot that as I only know IIS, but
    > they probably use OpenSSL and I think it has some good logging facilities.
    >
    > Best of luck on this one...
    >
    > Joe K.
    >
    > "Sholto Douglas" <> wrote in
    > message news:...
    >> Hi Joe,
    >> Still no progress.... However I do have a couple of pointers.
    >> Firstly when I try to bring up the web service in IE, I just get "The
    >> page
    >> cannot be displayed". On the Tomcat server they get exactly the same log
    >> message as when it fails from my app, and it dies at the same point
    >> (ServerHelloDone). Apparently the server is waiting for a certificate,
    >> which
    >> it doesn't get (either from my app, or from IE). I get no message
    >> prompting
    >> me for a client certificate.
    >> I have added the client key to the Personal folders of both the Local
    >> Machine store, and the Current User one. As I said, there is definitely
    >> a
    >> private key because when I try to export the certificate (in MMC), it
    >> prompts
    >> me if I want to export the private key.
    >> I have also added the root certificate to the Trusted Root Certification
    >> Authority in both stores. As you said, given that it is a console app,
    >> it
    >> should always have access to the Current User store.
    >>
    >> I activated the SCHANNEL logging, setting the value to 7 (i.e
    >> everything).
    >> However I only got one (Information) line - it just said "Creating an SSL
    >> client credential." There were no error messages, suggesting it bombed
    >> out
    >> early.
    >>
    >> Finally to see if the problem was TLS related, I removed the code that
    >> forced a TLS handshake (so it would default to SSLv3). Still failed.
    >>
    >> I appreciate your help Joe. This whole business is making me look very
    >> incompetent!
    >> --
    >> Cheers,
    >> Sholto
    >>
    >>
    >> "Joe Kaplan (MVP - ADSI)" wrote:
    >>
    >>> My guess is that you are going to want it in the machine store as the
    >>> account your web service client is running under will eventually change
    >>> to
    >>> the service process' account, but it should work in either for the
    >>> console
    >>> app as your user profile will be loaded.
    >>>
    >>> The MMC snap-in will tell you for sure if the client certificate has a
    >>> private key associated with it in the cert properties dialog. The
    >>> client
    >>> certificate should go in the personal store.
    >>>
    >>> You probably don't need the server's certificate on your machine at all
    >>> as
    >>> long as your machine trusts it.
    >>>
    >>> If you can't bring up the page in IE, that might mean that the
    >>> underlying
    >>> Wininet goo can't get to it either. Be careful with that as this might
    >>> not
    >>> be a client certificate issue at all.
    >>>
    >>> Another useful thing is to play with the schannel logging level to see
    >>> detailed log messages on the certificate exchange stuff in the event
    >>> log:
    >>> http://support.microsoft.com/?id=260729
    >>>
    >>> Joe K.

    >>

    >
    >
     
    Peter Jakab, Oct 7, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. C.W.
    Replies:
    1
    Views:
    5,946
  2. Ilias Lazaridis
    Replies:
    0
    Views:
    578
    Ilias Lazaridis
    Feb 1, 2005
  3. Dan  Orzechowski

    TLS/SSL handshaking errors

    Dan Orzechowski, Nov 30, 2005, in forum: Java
    Replies:
    0
    Views:
    1,067
    Dan Orzechowski
    Nov 30, 2005
  4. Jim Butler
    Replies:
    7
    Views:
    7,404
    Steven Cheng[MSFT]
    Jul 12, 2006
  5. Replies:
    0
    Views:
    475
Loading...

Share This Page