-
Notifications
You must be signed in to change notification settings - Fork 300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Payara 5.184: Client certificate negotiation has changed #3549
Comments
Can you create a test case on GitHub that reproduces the issue. |
Sorry for my late response. I'm currently setting up a test case and already discovered the following: Using Payara 5.183 requires Java 8u181 as of #3284. In this combination the behavior is correct (as always in 5.183). Using Payara 5.184 on Java 8u202 the behavior is broken (as described above). So this probably seems like a new incompatibility with JDK 8u191 and above? Or could this be related to the new domain.xml and new grizzly versions?:
|
Yes it could be related |
I've uploaded an example project (test case), to demonstrate the issue in the most simple way: https://github.com/KriechelD/Payara-3549-Test-Case |
Hello, adding a comment to this issue - I am also using Payara 5.184 with client certificate authentication. When the domain first starts, I am able to access my protected services using a client certificate (in my case, I am protecting Jersey 2 resources, but web.xml is substantively the same as the above). However, for unclear reasons, the client-cert authentication suddenly starts to fail with a 400 error. To trigger this sudden failure reliably, I use curl to try access the service as follows: curl --key key.pem --cert cert.pem --insecure -X POST https://127.0.0.1:8082/ws/restricted/admin Where key.pem and cert.pem are trusted certificates (meaning that this request should successfully pass certificate authentication, but clearly it is invalid because there is no post body). I have re-built Payara from source and the patched-src-grizzly project from source. I then placed the code in the debugger and found that in SSLBaseFilter.java, the variable renegotiationDisabled is set to false after my curl call whereas any web service requests before the curl call have that variable set to true. This makes no sense to me, but, the implication is that when the client-cert authentication fails, it is because the SSL client did not send its certificate for authentication. I have changed the following line in SSLBaseFilter.java (line 739) from: if (renegotiationDisabled) { to: if (renegotiationDisabled && !renegotiateOnClientAuthWant) { This seems to force renegotiation when it is truly needed because of a client auth, but I would appreciate an expert to look at this solution and advise. |
@shallem That's a good point and interessting finding. I can confirm that the renegotiation first works after a restart of the domain.
For Step 5, I'm not totally sure but it seems like a pattern: The renegotiation works in curl until I first call the webservice url with a browser (e.g. chrome doing HTTP GET just like calling a website). I don't know what exactly happens, but after a request with chrome that fails, the curl command stops working as well. |
This is exactly what I see - something triggers the service to stop working (either a browser call or a CURL request), and it never recovers thereafter. The fix that I proposed above has resolved my issue, although it is more of a workaround than a proper bug fix. |
Hi @KriechelD, I'm struggling to reproduce this bug. I've tried all combinations of 5.183 and 5.184 along with JDK 8u181 and 8u202 with your application deployed to the context root. I seem to get the same behaviour across all of the combinations, which is the server hanging for a time period (thread dumps seem to suggest it's waiting for a client certificate to be sent). The only exception seems to be 5.183 on 8u202. Are there any extra steps necessary to reproduce? As a side note, disabling HTTP/2 seems to cause the connection to be closed as you say. Do you notice the same? I suspect this is because HTTP/2 has no support for client certificates. Regardless, I think the behaviour should at least be consistent so I'd like to be able to reproduce this. Kind regards, Matt |
Hello @MattGill98 thanks for your response 😃 From my perspective, there are no extra steps necassary to reproduce. But I've created a short clip just to be sure nothing is missed: https://youtu.be/H6oKY-ge4Xc If you require any more information or another video for a different combinations let me know. All combinations follow the exact same flow, just with another java or payara version. For HTTP/2: You are right with disabling HTTP/2: Unchecking HTTP/2 will make certificate authentication work again in 5.184 as it did in 5.183. Interessting findings. But client-certificate is taken care of by the underlying TLS, isn't it? 🤔 Best regards, |
My understanding is the Client cert authentication is not supported in HTTP/2. |
Hi @KriechelD, Thank you for the video, it was helpful! HTTP/2 requires a TLS extension as per JEP 244, and it also doesn't support client certificates. I believe the behaviour you experienced in 5.183 was caused by HTTP/2 being disabled due to an unsupported JDK version. Because 5.184 doesn't have this issue (all JDK 8 versions should be supported), HTTP/2 isn't being disabled, which is causing the issue. I've created I hope this clarifies things somewhat! Kind regards, Matt |
Hello Matt, thanks for the clarification, your explanation makes sense to me. I took a quick search on google and could find the inital discussions on why HTTP/2 is not supporting client certificates at the moment: https://mailarchive.ietf.org/arch/msg/httpbisa/gAINpj1KJu0ZgYf9NcD23-1WVTQ It seems like they are still in the specification phase: https://tools.ietf.org/html/draft-ietf-httpbis-http2-secondary-certs-03 Therefore I will close the ticket as the problem is HTTP/2 instead of payara. Best regards, |
Description
In Payara 5.184 there have been some changes under the hood, related to the security implementation such as client certificate authentication: https://blog.payara.fish/new-feature-in-payara-server-5.184-allow-use-of-different-security-providers-via-jce-api
The server now behaves differently for client-certificates.
Expected Outcome
Opening a secured URL (which requires a client certificate) in Chrome-Browser (or any other Browser) should bring a Pop-Up asking to select an appropriate certificate.
Current Outcome
In Payara 5.183 this worked fine. But in 5.184 the side is just loading forever and after some time the connection gets closed.
Steps to reproduce
Simply create a Web-Project (.war) containing something like this in web.xml:
Open an URL of this project in the Browser. You won't get a popup and the site will not load at all.
If you do a check using curl, this is the output for 5.183:
As you can see, the TLS-Handshake is occuring again, because the application requires a client certificate. error:140940E5:SSL show the Browser, that a client certificate is required and it can therefore promt the user to select one.
This is not happening in Payara 5.184:
The request is always answered with an HTTP 400 and the connection is closed. And therefore the connection is broken.
Addition
This behavoir is not occuring, when forcing a client-certificate on the server:
Once this is checked (and server was restarted) the browser pops up correctly. But having this checked, all applications on the server ask for a client certificate. So this breaks the mechanism of having an optional client-certificate, which is a mandatory feature.
Environment
The text was updated successfully, but these errors were encountered: