Re: Tomcat 10.1.36 Configuration Question: Client Certificate(s) missing from servlet request object

2025-02-26 Thread Christopher Schultz

Robert,

On 2/25/25 5:59 PM, Robert Turner wrote:

Tomcat 10.x uses the jakarta versions of the API, and I believe all the
attributes have been renamed:

"javax.servlet.request.X509Certificate" ->
"jakarta.servlet.request.X509Certificate"


+1

This is documented in Jakarta Servlet Specification[1] section 3.11.

-chris

[1] 
https://jakarta.ee/specifications/servlet/6.0/jakarta-servlet-spec-6.0.pdf



On Tue, Feb 25, 2025 at 4:45 PM Chris Evans  wrote:



Hello,

I need assistance with accessing client certificates from a servlet.  This
is not a servlet code question but a configuration question.  The call to:
request.getAttribute("javax.servlet.request.X509Certificate");

is not returning any certificates.  The last time that I needed to do this
was Tomcat 7 and a lot has changed.

When connecting with a browser, a trusted connection is established.
Javax.net.debug output shows my client certificate and a complete
chain have been accepted.

I have also limited the TLS version to TSSv1.2.

What have I missed?

Thanks,

Chris Evans

OS: Ubuntu 22-04
Tomcat Version: 10.1.36

TLS Logging:
env | grep OPT
CATALINA_OPTS=-Djavax.net.debug=ssl,handshake

Connector Configuration:

   

 

   

Java:
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
 @Override
 protected void doGet(HttpServletRequest request, HttpServletResponse
response)
 throws ServletException, IOException {
 System.out.println("HelloServlet");
 response.setContentType("text/html");
 response.getWriter().println("Hello, World!");
 // Retrieve client certificate
 X509Certificate[] certs = (X509Certificate[])
request.getAttribute("javax.servlet.request.X509Certificate");

 if (certs != null && certs.length > 0) {
 response.getWriter().println("Client Cert Subject: " +
certs[0].getSubjectX500Principal());
 } else {
 response.getWriter().println("No Client Certificate Found.");
 }

 }
}

WARNINGS:
javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
20:34:04.816 UTC|SSLExtensions.java:227|Ignore impact of unsupported
extension: server_name
javax.net.ssl|DEBUG|21|https-jsse-nio2-8443-exec-2|2025-02-25 20:34:04.817
UTC|SSLExtensions.java:219|Ignore unavailable extension: max_fragment_length
javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
20:34:04.817 UTC|SSLExtensions.java:227|Ignore impact of unsupported
extension: status_request
javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
20:34:04.818 UTC|SSLExtensions.java:227|Ignore impact of unsupported
extension: supported_groups
javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
20:34:04.818 UTC|SSLExtensions.java:227|Ignore impact of unsupported
extension: ec_point_formats
javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
20:34:04.821 UTC|SSLExtensions.java:227|Ignore impact of unsupported
extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|21|https-jsse-nio2-8443-exec-2|2025-02-25 20:34:04.821
UTC|SSLExtensions.java:219|Ignore unavailable extension: status_request_v2
javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
20:34:04.823 UTC|SSLExtensions.java:227|Ignore impact of unsupported
extension: extended_master_secret


PROPRIETARY INFORMATION. This email may contain proprietary and privileged
material for the sole use of the intended recipient. Any review or
distribution of such material by others is strictly prohibited. If you are
not the intended recipient please contact the sender and delete all copies.






-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



RE: Tomcat 10.1.36 Configuration Question: Client Certificate(s) missing from servlet request object

2025-02-26 Thread Chris Evans
Thanks for the help.

Best regards,

Chris Evans


-Original Message-
From: Christopher Schultz 
Sent: Wednesday, February 26, 2025 7:38 AM
To: users@tomcat.apache.org
Subject: Re: Tomcat 10.1.36 Configuration Question: Client Certificate(s) 
missing from servlet request object

Robert,

On 2/25/25 5:59 PM, Robert Turner wrote:
> Tomcat 10.x uses the jakarta versions of the API, and I believe all
> the attributes have been renamed:
>
> "javax.servlet.request.X509Certificate" ->
> "jakarta.servlet.request.X509Certificate"

+1

This is documented in Jakarta Servlet Specification[1] section 3.11.

-chris

[1]
https://jakarta.ee/specifications/servlet/6.0/jakarta-servlet-spec-6.0.pdf

> On Tue, Feb 25, 2025 at 4:45 PM Chris Evans  wrote:
>
>>
>> Hello,
>>
>> I need assistance with accessing client certificates from a servlet.
>> This is not a servlet code question but a configuration question.  The call 
>> to:
>> request.getAttribute("javax.servlet.request.X509Certificate");
>>
>> is not returning any certificates.  The last time that I needed to do
>> this was Tomcat 7 and a lot has changed.
>>
>> When connecting with a browser, a trusted connection is established.
>> Javax.net.debug output shows my client certificate and a complete
>> chain have been accepted.
>>
>> I have also limited the TLS version to TSSv1.2.
>>
>> What have I missed?
>>
>> Thanks,
>>
>> Chris Evans
>>
>> OS: Ubuntu 22-04
>> Tomcat Version: 10.1.36
>>
>> TLS Logging:
>> env | grep OPT
>> CATALINA_OPTS=-Djavax.net.debug=ssl,handshake
>>
>> Connector Configuration:
>>
>>> protocol="org.apache.coyote.http11.Http11Nio2Protocol"
>>
>>   sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
>> maxParameterCount="1000"
>> scheme="https"
>> xmlValidation="true"
>> maxThreads="150"
>> SSLEnabled="true"
>> secure="true"
>>>
>> >  certificateVerificationDepth="4"
>>  truststoreFile="/home/ubuntu/tomcat/-REDACTED-.jks"
>>  truststorePassword="-REDACTED-"
>>  protocols="TLSv1.2"
>>  certificateVerification="required"
>>
>> >
>>  > certificateFile="/home/ubuntu/tomcat/serverCert.pem"
>>
>>   certificateChainFile="/home/ubuntu/tomcat/serverChain.pem"
>>
>>   certificateKeyFile="/home/ubuntu/tomcat/rsaKey.pem"
>>   type="RSA" />
>> 
>>
>>
>> Java:
>> @WebServlet("/hello")
>> public class HelloServlet extends HttpServlet {
>>  @Override
>>  protected void doGet(HttpServletRequest request,
>> HttpServletResponse
>> response)
>>  throws ServletException, IOException {
>>  System.out.println("HelloServlet");
>>  response.setContentType("text/html");
>>  response.getWriter().println("Hello, World!");
>>  // Retrieve client certificate
>>  X509Certificate[] certs = (X509Certificate[])
>> request.getAttribute("javax.servlet.request.X509Certificate");
>>
>>  if (certs != null && certs.length > 0) {
>>  response.getWriter().println("Client Cert Subject: " +
>> certs[0].getSubjectX500Principal());
>>  } else {
>>  response.getWriter().println("No Client Certificate Found.");
>>  }
>>
>>  }
>> }
>>
>> WARNINGS:
>> javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
>> 20:34:04.816 UTC|SSLExtensions.java:227|Ignore impact of unsupported
>> extension: server_name
>> javax.net.ssl|DEBUG|21|https-jsse-nio2-8443-exec-2|2025-02-25
>> 20:34:04.817
>> UTC|SSLExtensions.java:219|Ignore unavailable extension:
>> UTC|max_fragment_length
>> javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
>> 20:34:04.817 UTC|SSLExtensions.java:227|Ignore impact of unsupported
>> extension: status_request
>> javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
>> 20:34:04.818 UTC|SSLExtensions.java:227|Ignore impact of unsupported
>> extension: supported_groups
>> javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
>> 20:34:04.818 UTC|SSLExtensions.java:227|Ignore impact of unsupported
>> extension: ec_point_formats
>> javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
>> 20:34:04.821 UTC|SSLExtensions.java:227|Ignore impact of unsupported
>> extension: application_layer_protocol_negotiation
>> javax.net.ssl|DEBUG|21|https-jsse-nio2-8443-exec-2|2025-02-25
>> 20:34:04.821
>> UTC|SSLExtensions.java:219|Ignore unavailable extension:
>> UTC|status_request_v2
>> javax.net.ssl|WARNING|21|https-jsse-nio2-8443-exec-2|2025-02-25
>> 20:34:04.823 UTC|SSLExtensions.java:227|Ignore impact of unsupported
>> extension: extended_master_secret
>>
>>
>> PROPRIETARY INFORMATION. This email may contain proprietary and
>> privileged material for the sole use of the intended recipient. Any
>> rev

Re: tomcat 10.1.33 random rare 500 response status for http2 upgrade with tls

2025-02-26 Thread Mark Thomas

On 26/02/2025 12:04, Mark Thomas wrote:

On 26/02/2025 08:16, Mark Thomas wrote:

On 13/02/2025 10:04, Rémy Maucherat wrote:
On Thu, Feb 13, 2025 at 9:41 AM Cenk Pekyaman 
 wrote:


We run tomcat on java17 with the embedded tomcat setup.
We have http and https connectors and we have http2 upgradeProtocol for
both.

We recently upgraded from 9.0.88 to 10.1.24 to work on javax to jakarta
migration, and after a while, upgraded to 10.1.33.
After the upgrade, we started to see random and rare 500 errors for 
some of

the http2 GET requests over https.
When reproducing the error on our development machines, we could see 
the

following trace on the server:
```
  java.io.IOException: null


Tomcat now sets an IO exception to trigger ReadListener.onError with
an appropriate error in that case. So things seem normal so far.


Following up on this.

Tomcat is behaving as if the client has reset the stream before the 
client sent all of the data. If that is what the client is doing then 
this behaviour is expected. However, that then raises the question why 
is the reset being sent. If the client isn't resetting the stream then 
there is definitely a Tomcat bug here. We need to look at the test 
case you've provided. I'm planning on starting that today.


Thanks again for the test case. It makes debugging issues so much easier 
when the report includes a reproducible test case.


I am able to reproduce this issue with the latest 12.0.x code.

It does look like there is a Tomcat bug here. I am currently working on 
tracking down the root cause.


Found it and fixed the issue. The fix will be in the March releases.

Mark


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: tomcat 10.1.33 random rare 500 response status for http2 upgrade with tls

2025-02-26 Thread Mark Thomas

On 13/02/2025 10:04, Rémy Maucherat wrote:

On Thu, Feb 13, 2025 at 9:41 AM Cenk Pekyaman  wrote:


We run tomcat on java17 with the embedded tomcat setup.
We have http and https connectors and we have http2 upgradeProtocol for
both.

We recently upgraded from 9.0.88 to 10.1.24 to work on javax to jakarta
migration, and after a while, upgraded to 10.1.33.
After the upgrade, we started to see random and rare 500 errors for some of
the http2 GET requests over https.
When reproducing the error on our development machines, we could see the
following trace on the server:
```
  java.io.IOException: null


Tomcat now sets an IO exception to trigger ReadListener.onError with
an appropriate error in that case. So things seem normal so far.


Following up on this.

Tomcat is behaving as if the client has reset the stream before the 
client sent all of the data. If that is what the client is doing then 
this behaviour is expected. However, that then raises the question why 
is the reset being sent. If the client isn't resetting the stream then 
there is definitely a Tomcat bug here. We need to look at the test case 
you've provided. I'm planning on starting that today.



Now the "null" is not normal, the corresponding string exists in the
resource bundle:
stream.clientResetRequest=Client reset the stream before the request
was fully read


This is a Tomcat bug. The resource string was missing in 10.1.33 and was 
added for 10.1.35 onwards.


Mark



Rémy


   at
org.apache.coyote.http2.Stream$StandardStreamInputBuffer.receiveReset(Stream.java:1516)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at org.apache.coyote.http2.Stream.receiveReset(Stream.java:224)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at
org.apache.coyote.http2.Http2UpgradeHandler.close(Http2UpgradeHandler.java:1305)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at
org.apache.coyote.http2.Http2UpgradeHandler.upgradeDispatch(Http2UpgradeHandler.java:437)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at
org.apache.coyote.http2.Http2AsyncUpgradeHandler.upgradeDispatch(Http2AsyncUpgradeHandler.java:43)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at
org.apache.coyote.http2.Http2AsyncParser$FrameCompletionHandler.failed(Http2AsyncParser.java:337)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at
org.apache.coyote.http2.Http2AsyncParser$FrameCompletionHandler.failed(Http2AsyncParser.java:167)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at
org.apache.tomcat.util.net.SocketWrapperBase$VectoredIOCompletionHandler.failed(SocketWrapperBase.java:1148)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at
org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper$NioOperationState.run(NioEndpoint.java:1660)
~[tomcat-coyote-10.1.33.jar:10.1.33]
   at
org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
[tomcat-util-10.1.33.jar:10.1.33]
   at
org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
[tomcat-util-10.1.33.jar:10.1.33]
   at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
[tomcat-util-10.1.33.jar:10.1.33]
   at java.lang.Thread.run(Thread.java:840) [?:?]
```

after further testing, we think the change
https://github.com/apache/tomcat/commit/f902edf085c0c73139a66d1bfc4d5790a416b130
introduced in 10.1.29 is the reason we get 500 status.
but the change seems to be doing what is intended, so we tested with
multiple tomcat versions to see if there were already unexposed failures
prior.
and in versions like 10.1.24 we see the below error which does not result
in 500 status:
```
[org.apache.coyote.http2.Http2Parser] {https-jsse-nio-8443-exec-6}
Connection [92], Stream [0], Frame type [null], Error
   java.io.IOException: Unable to unwrap data, invalid status [CLOSED]
   at
org.apache.tomcat.util.net.SecureNioChannel.read(SecureNioChannel.java:772)
~[tomcat-coyote-10.1.24.jar:10.1.24]
   at
org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper$NioOperationState.run(NioEndpoint.java:1609)
~[tomcat-coyote-10.1.24.jar:10.1.24]
   at
org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
[tomcat-util-10.1.24.jar:10.1.24]
   at
org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
[tomcat-util-10.1.24.jar:10.1.24]
   at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
[tomcat-util-10.1.24.jar:10.1.24]
   at java.base/java.lang.Thread.run(Thread.java:840) [?:?]
```
it is not the same error, but since it is happening around the same code
context NioOperationState.run, it gave us the impression that the traces
might be related.

We have run our reproducer with multiple versions: 10.1.24, 10.1.28,
10.1.29, 10.1.33, 10.1.35, 11.0.2.
versions 10.1.29 and up show the rarer "receiveReset" issue (500 status),
versions 10.1.28 and down showcase only "Unable to unwrap data" issue (no
500).

We can reproduce the issue somewhat reliably with the reproducer setup we
have in https://github.com/cpekyaman/java-server-http2-te

Re: tomcat 10.1.33 random rare 500 response status for http2 upgrade with tls

2025-02-26 Thread Mark Thomas

On 26/02/2025 08:16, Mark Thomas wrote:

On 13/02/2025 10:04, Rémy Maucherat wrote:
On Thu, Feb 13, 2025 at 9:41 AM Cenk Pekyaman  
wrote:


We run tomcat on java17 with the embedded tomcat setup.
We have http and https connectors and we have http2 upgradeProtocol for
both.

We recently upgraded from 9.0.88 to 10.1.24 to work on javax to jakarta
migration, and after a while, upgraded to 10.1.33.
After the upgrade, we started to see random and rare 500 errors for 
some of

the http2 GET requests over https.
When reproducing the error on our development machines, we could see the
following trace on the server:
```
  java.io.IOException: null


Tomcat now sets an IO exception to trigger ReadListener.onError with
an appropriate error in that case. So things seem normal so far.


Following up on this.

Tomcat is behaving as if the client has reset the stream before the 
client sent all of the data. If that is what the client is doing then 
this behaviour is expected. However, that then raises the question why 
is the reset being sent. If the client isn't resetting the stream then 
there is definitely a Tomcat bug here. We need to look at the test case 
you've provided. I'm planning on starting that today.


Thanks again for the test case. It makes debugging issues so much easier 
when the report includes a reproducible test case.


I am able to reproduce this issue with the latest 12.0.x code.

It does look like there is a Tomcat bug here. I am currently working on 
tracking down the root cause.


Mark

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org