ReactiveX / RxNetty

Reactive Extension (Rx) Adaptor for Netty
Apache License 2.0
1.38k stars 254 forks source link

HTTPS Server with RxNetty and existing certificate #621

Open ikey-ru opened 3 years ago

ikey-ru commented 3 years ago

Hi! I'm trying to write microservice using RxNetty and stuck on implementing HTTPS support for it. I have certificate chain in PEM format and a private key for domain ikeybase.ru, that are already in used in Apache that serves website and in some other services at this domain. I have following code for starting server:

    fun start() {
        server = HttpServer.newServer(environment.serverConfiguration.port)
        environment.serverConfiguration.sslConfiguration.let { ssl ->
            if(ssl != null) {
                val certFile = File(ssl.certificatePath)
                val keyFile = File(ssl.privatePath)
                val sslContext = SslContextBuilder.forServer(certFile.inputStream(), keyFile.inputStream())
                    .sslProvider(SslProvider.JDK)
                    .clientAuth(ClientAuth.REQUIRE)
                    .build()
                val sslEngine = sslContext.newEngine(UnpooledByteBufAllocator.DEFAULT, "ikeybase.ru", 2228)
                server = server.secure(sslEngine)
                server.start { httpRequest, httpResponse ->
                    router.route(httpRequest, httpResponse)
                }
            } else {
                server.start { httpRequest, httpResponse ->
                    router.route(httpRequest, httpResponse)
                }
            }
        }
    }

where ssl.certificatePath is path to PEM ca-bundle and ssl.privatePath is path to private key, converted from *.key file to pk8 format with following command:

openssl pkcs8 -topk8 -inform PEM -outform PEM -in ikeybase.key -out ikeybase.pk8 -nocrypt

After starting server with sslConfiguration defined, server seems to be started normally, however when I'm trying to access any content, nothing happens. Router.route not called and I got following error at first service query and no output at others, however, when sslConfiguration not defined, server runs perfectly:

// HTTPS on (sslConfiguration defined):
curl -i "https://ikeybase.ru:2228/"
curl: (35) error:0407E086:rsa routines:RSA_verify_PKCS1_PSS_mgf1:last octet invalid
curl -v "https://ikeybase.ru:2228/"
*   Trying 94.188.60.102:2228...
* TCP_NODELAY set
* Connected to ikeybase.ru (94.188.60.102) port 2228 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (OUT), TLS alert, decrypt error (563):
* error:0407E086:rsa routines:RSA_verify_PKCS1_PSS_mgf1:last octet invalid
* Closing connection 0
curl: (35) error:0407E086:rsa routines:RSA_verify_PKCS1_PSS_mgf1:last octet invalid
// HTTPS off (no sslConfiguration defined):
curl -i "http://ikeybase.ru:2228/"
HTTP/1.1 200 OK
content-length: 190

{
  "serverName": "iKey Share",
  "serverVersion": "v0.0.1",
  "instanceName": "iKey Share",
  "httpErrorsAmountSinceStarted": 0,
  "uptime": "00 days : 00 hours : 00 minutes : 16 seconds"
}

Gradle setup:

    // Server dependencies
    //compile group: 'io.netty', name: 'netty-all', version: '4.1.59.Final'
    compile group: 'io.netty', name: 'netty-all', version: '4.1.31.Final'
    compile 'io.reactivex:rxnetty-http:0.5.3'
    compile 'io.reactivex:rxnetty-tcp:0.5.3'
    compile 'io.reactivex:rxnetty-common:0.5.3'
    compile 'io.reactivex:rxnetty-spectator-http:0.5.3'
    compile 'io.reactivex:rxnetty-spectator-tcp:0.5.3'
    compile 'io.reactivex:rxjava:1.2.+'

How can I use HTTPS certificate and pkey to enable HTTPS support for server side RxNetty? Any help appreciated, thanks in advance!