2

I have a Java 8 client/server application which is failing TLS negotiation when using a ClientAuth certificate:

javax.net.ssl.SSLHandshakeException: Invalid CertificateVerify signature

The app uses an embedded jetty instance to provide a REST API to a Vaadin application running in the same process.

When the application makes a REST request which does not require a ClientAuth response the request is fine.

As some other posts here have mentioned I tried -Djdk.tls.disabledAlgorithms=RSASSA-PSS and that had no effect.

Problem exists with eclipse openjdk 8u282, 8u302, 8u322.

Full debug below with edits for brevity:

javax.net.ssl|FINE|34|IDLE session T52|2022-03-23 10:28:17.772 PDT|CertificateMessage.java:372|Consuming client Certificate handshake message (
"Certificates": [
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "65 00 00 0E 6C ED 9A D7 F1 D4 70 A2 56 00 01 00 00 0E 6C",
    "signature algorithm": "SHA384withRSA",
    "issuer"             : "CN=Acme Issuing CA1, DC=corp, DC=acme, DC=com",
    "not before"         : "2022-03-17 11:02:03.000 PDT",
    "not  after"         : "2023-03-17 11:02:03.000 PDT",
    "subject"            : "CN=mikevdev.corp.acme.com",
    "subject public key" : "RSA",
    "extensions"         : [
      {
        ObjectId: 2.5.29.37 Criticality=false
        ExtendedKeyUsages [
          clientAuth
          serverAuth
        ]
      },
      {
        ObjectId: 2.5.29.17 Criticality=false
        SubjectAlternativeName [
          DNSName: mikevdev.corp.acme.com
        ]
      },
    ]},
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "56 00 00 00 06 10 D8 F4 6B 40 ED F7 89 00 00 00 00 00 06",
    "signature algorithm": "SHA384withRSA",
    "issuer"             : "CN=Acme Root CA",
    "not before"         : "2020-08-17 13:30:35.000 PDT",
    "not  after"         : "2030-08-17 13:40:35.000 PDT",
    "subject"            : "CN=Acme Issuing CA1, DC=corp, DC=acme, DC=com",
    "subject public key" : "RSA",
    "extensions"         : [
    ]},
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "18 54 B2 02 37 98 9E BA 45 02 66 B3 B8 B6 9D C8",
    "signature algorithm": "SHA384withRSA",
    "issuer"             : "CN=Acme Root CA",
    "not before"         : "2020-08-14 13:10:21.000 PDT",
    "not  after"         : "2040-08-14 13:20:20.000 PDT",
    "subject"            : "CN=Acme Root CA",
    "subject public key" : "RSA",
    "extensions"         : [
    ]}
]
)
javax.net.ssl|FINE|34|IDLE session T52|2022-03-23 10:28:17.777 PDT|ECDHClientKeyExchange.java:486|Consuming ECDHE ClientKeyExchange handshake message (
"ECDH ClientKeyExchange": {
  "ecdh public": {
}
)
javax.net.ssl|FINE|21|qtp1622160793-33|2022-03-23 10:28:17.779 PDT|CertificateVerify.java:763|Produced CertificateVerify handshake message (
"CertificateVerify": {
  "signature algorithm": rsa_pss_rsae_sha256
  "signature": {
    0000: 2B D7 85 1C 75 B0 53 7E   F0 AC 74 9A 60 DA 61 EF  +...u.S...t.`.a
  }
}
)
javax.net.ssl|FINE|21|qtp1622160793-33|2022-03-23 10:28:17.779 PDT|ChangeCipherSpec.java:115|Produced ChangeCipherSpec message
javax.net.ssl|FINE|21|qtp1622160793-33|2022-03-23 10:28:17.780 PDT|Finished.java:393|Produced client Finished handshake message (
"Finished": {
  "verify data": {
    0000: A3 22 70 01 CB 3F 71 8A   97 F3 35 7C
  }'}
)
javax.net.ssl|SEVERE|31|qtp1622160793-49|2022-03-23 10:28:17.780 PDT|TransportContext.java:316|Fatal (HANDSHAKE_FAILURE): Invalid CertificateVerify signature (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: Invalid CertificateVerify signature
        at sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:311)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:267)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:258)
        at sun.security.ssl.CertificateVerify$T12CertificateVerifyMessage.<init>(CertificateVerify.java:672)
        at sun.security.ssl.CertificateVerify$T12CertificateVerifyConsumer.consume(CertificateVerify.java:802)
        at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:377)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
        at sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:968)
        at sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:955)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:902)
        at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.fill(SslConnection.java:639)
        at org.eclipse.jetty.server.HttpConnection.fillRequestBuffer(HttpConnection.java:345)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
        at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:540)
        at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:395)
        at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:161)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
        at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:383)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
        at java.lang.Thread.run(Thread.java:748)}
Mike Cooper
  • 1,065
  • 3
  • 13
  • 34
  • Do you have installed the unlimited strength extension for JDK (https://www.oracle.com/java/technologies/javase/jceunlimitedstrghpolicyfilereadme.html). Also check this https://stackoverflow.com/questions/62930842/how-to-fix-sslhandshakeexception-invalid-certificateverify-signature – pringi Mar 30 '22 at 16:40
  • 2
    @pringi openjdk doesn't need to enable the unrestricted policy for JCE, it affects only to Oracle JVMs; even in the later case, JCE unrestricted policy is enabled by default in Oracle JVM since 8u161. – jccampanero Mar 30 '22 at 22:30
  • @pringi I did check the post your referenced prior to posting my question. The solution of updating the JDK doesn't work in my case. I've tried multiple jdk8 builds including the latest as noted. – Mike Cooper Apr 01 '22 at 00:36
  • `jdk.tls.disabledAlgorithms` is a _security_ property; it cannot be set with `-D`. But I doubt your problem is [RSA]PSS; 8u261 up support it, since it's required for 1.3. To be clear: both client and server are in the same JVM, and in this log? And the log at 2022-03-23 10:28:17.779 has been editted and the actual signature is NOT 16 bytes, but more like 256 or 384? If you simplify your (jetty) server to just accept a request (but not actually do anything) and your client to just make one request, and that reproduces the problem, could you post them as an MRE? – dave_thompson_085 May 01 '22 at 10:08

1 Answers1

0

I tried reproducing your issue. However, I'm getting successful TLS Negotiation