ptrd / kwik

A QUIC client, client library and server implementation in Java. Supports HTTP3 with "Flupke" add-on.
GNU General Public License v3.0
390 stars 57 forks source link

Handshake error - unable to find valid certification path to requested target #10

Closed judos closed 3 years ago

judos commented 3 years ago

Hi, I'm trying your examples (from readme) to learn how I would use kwik in a project. For testing I created self signed cert/key files using openssl:

openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem

Then I ran server and client as follows (with output). Server:

PS D:\Downloads> java -cp kwik.jar net.luminis.quic.server.Server cert-win1252.pem key-win1252.pem 11014 "D:\Downloads\"
21-08-09T16:09:57.236 Kwik server 95be892-dirty started; supported application protcols: [hq-29, hq-30, hq-interop, hq-32, hq-31]
21-08-09T16:10:04.484 Creating new connection with version QUIC_version_1 for odcid b4ac2ea3f3bb1128 with 127.0.0.1: c6c579f3
21-08-09T16:10:05.017 Error: Connection closed by peer with TLS error 42: unable to find valid certification path to requested target

Client:

PS D:\Downloads> java -jar kwik.jar localhost:11014 --clientCertificate "cert-win1252.pem" --clientKey "key-win1252.pem" -H '/index.html'
10:16.211 Creating connection with localhost:11014 with QUIC_version_1
10:16.311 Original destination connection id: 8554d7f3b3a059a1 (scid: 3b21a724900427e0)
          >- CryptoStream[I|ClientHello]
10:16.817 <- (1) Packet I|-|R|72| Retry Token (37): c6c337def7292561292d4760661db29e94fef51be8b5041a9948de9deca40f2b1db70f7b88
          >- CryptoStream[I|ClientHello,ClientHello]
10:16.811 -> Packet I|0|L|1200|2  Token=[] CryptoFrame[0,251] Padding(902)
10:16.884 -> Packet I|1|L|1200|2  Token=c6c337def7292561292d4760661db29e94fef51be8b5041a9948de9deca40f2b1db70f7b88 CryptoFrame[0,251] Padding(869)
10:16.949 <- (2) Packet I|0|L|171|2  Token=[] AckFrame[1|?0] CryptoFrame[0,123]
          -< CryptoStream[I|ServerHello]
10:17.012 -> Packet I|2|L|1201|2  Token=c6c337def7292561292d4760661db29e94fef51be8b5041a9948de9deca40f2b1db70f7b88 AckFrame[0|?0] Padding(1120)
10:16.949 <- (2) Packet H|0|L|1052|1  CryptoFrame[0,1010]
          -< CryptoStream[H|EncryptedExtensions]
10:17.017 -> Packet H|0|L|42|1  AckFrame[0|?0]
10:17.033 Error: Inconsistency error in congestion controller; attempt to set bytes in-flight below 0
10:17.033 getPtoTimeAndSpace: no ack eliciting in flight and but handshake keys -> H
10:16.950 <- (3) Packet H|1|L|1122|1  CryptoFrame[1010,1079]
10:17.134 -> Packet H|1|L|107|2  AckFrame[1-0|?0] ConnectionCloseFrame[298|0|unable to find valid certification path to requested target]
10:17.134 <- (4) Packet H|2|L|46|2  ConnectionCloseFrame[0|0|] AckFrame[1-0|?0]
Got IO error: java.net.ConnectException: Handshake error

How can I fix the error I get? Did I misunderstand any of the options provided for the example?

TLS Error 42 means "Bad certificate" (https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_record) Is this because it is a self-signed certificate? Does it need to be in a certificate chain and publicly verifiable?

Thanks for your help!

ptrd commented 3 years ago

Hi, This is indeed caused by having a self-signed certificate. You can pass the --noCertificateCheck option to the client to make it skip the certificate check. By the way, you don't have to pass certificate (and key) with the client, this is only necessary when the server requires client authentication. Hth! Regards Peter

judos commented 3 years ago

Thanks for the reply. Now it works!

In Detail: I removed the client cert/key for the client and added argument to ignore the server certificate (because it is self-signed at the moment). Also I had to change the certificate because servername of the certificate (localhost here) is verified by the client.

server

java -cp kwik.jar net.luminis.quic.server.Server cert-win-lb.pem key-win-lb.pem 11014 "D:\Downloads\"

client

java -jar kwik.jar localhost:11014 -H 'index.html' --noCertificateCheck
[...]
00:09.230 -> Packet A|2|S0|8617f3da|27|1  AckFrame[2-0|Δ4]
Server returns: 
Hello World!
00:09.746 -> Packet A|3|S0|8617f3da|31|2  ConnectionCloseFrame[0|0|] AckFrame[2-0|Δ0]

Maybe this would be a good example how to use the library, provided all needed files (kwik.jar + test certs) and basic command how to try it out): test.zip

ptrd commented 3 years ago

Thanks for the feedback. I read in your notes that you had to replace line breaks in the key file (and probably in the certificate file too), if you want you can create an issue for that, should be easy to fix. Regards Peter

judos commented 3 years ago

No worries. For the issue with the line breaks I checked your code and saw that you read the certificate with default system encoding. I guess because I created the certificates with LinuxSubsystem on Windows it's a bit weird. But I assume your code is correct :) Best regards, Julian