OIDCProviderConfigurationRequest does not send SNI info in TLS handshake

Issue #384 open
Pascal Knüppel created an issue

We got a problem with the nimbus oauth2 and oidc sdk. We are using keycloak within a kubernetes cluster and we are overriding the kubernetes-clusters tls certificate for the keycloak nodes. Now if we try to access the openid-configuration with the “OIDCProviderConfigurationRequest“ we get a certificate error since the implementation is using: HttpURLConnection conn = this.toHttpURLConnection();`. The underlying http client is from sun and outdated. It does not send SNI info during TLS-handshake:

CONNECT my-keycloak:443 HTTP/1.1
User-Agent: Java/11.0.12
Host: my-keycloak
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.

Version: 3.3 (TLS/1.2)
Random: 84 0D 1B BC C9 AE 2D F7 84 02 CE BA 5E 68 3E 71 25 61 35 52 78 22 24 01 BA 66 03 A9 4C 3B B0 AB
"Time": 02.01.2070 12:59:00
SessionID: 50 05 B6 B6 21 70 F6 E2 9C 8E 09 8E 96 5E 88 04 CF 12 1F A7 E4 A6 5F 73 EE 67 F9 5F 8A 91 57 E8
Extensions: 
    status_request  OCSP - Implicit Responder
    supported_groups    x25519 [0x1d], secp256r1 [0x17], secp384r1 [0x18], secp521r1 [0x19], x448 [0x1e], ffdhe2048 [0x0100], ffdhe3072 [0x0101], ffdhe4096 [0x0102], ffdhe6144 [0x0103], ffdhe8192 [0x0104]
    ec_point_formats    uncompressed [0x0]
    signature_algs  ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1
    signature_algorithms_cert   ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1
    status_request_v2 (RFC6961) 00 07 02 00 04 00 00 00 00
    extended_master_secret  empty
    supported_versions  Tls1.3, Tls1.2
    psk_key_exchange_modes  01 01
    key_share   00 24 00 1D 00 20 07 6F 65 8A C5 1B EE AD DA 1C 51 88 74 2F F0 7D 07 33 BF 22 39 8E 89 80 BA 3A 9B D2 A5 78 E0 42
Ciphers: 
    [1301]  TLS_AES_128_GCM_SHA256
    [1302]  TLS_AES_256_GCM_SHA384
    [C02C]  TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    [C02B]  TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    [C030]  TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    [009D]  TLS_RSA_WITH_AES_256_GCM_SHA384
    [C02E]  TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
    [C032]  TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
    [009F]  TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
    [00A3]  TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
    [C02F]  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    [009C]  TLS_RSA_WITH_AES_128_GCM_SHA256
    [C02D]  TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
    [C031]  TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
    [009E]  TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    [00A2]  TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
    [C024]  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    [C028]  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    [003D]  TLS_RSA_WITH_AES_256_CBC_SHA256
    [C026]  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
    [C02A]  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
    [006B]  TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
    [006A]  TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
    [C00A]  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    [C014]  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    [0035]  TLS_RSA_WITH_AES_256_CBC_SHA
    [C005]  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
    [C00F]  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
    [0039]  TLS_DHE_RSA_WITH_AES_256_CBC_SHA
    [0038]  TLS_DHE_DSS_WITH_AES_256_CBC_SHA
    [C023]  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    [C027]  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    [003C]  TLS_RSA_WITH_AES_128_CBC_SHA256
    [C025]  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
    [C029]  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
    [0067]  TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
    [0040]  TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
    [C009]  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    [C013]  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
    [002F]  TLS_RSA_WITH_AES_128_CBC_SHA
    [C004]  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
    [C00E]  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
    [0033]  TLS_DHE_RSA_WITH_AES_128_CBC_SHA
    [0032]  TLS_DHE_DSS_WITH_AES_128_CBC_SHA
    [00FF]  TLS_EMPTY_RENEGOTIATION_INFO_SCSV

Compression: 
    [00]    NO_COMPRESSION

thus the handshake fails because the nginx-ingress-controller returns the wrong certificate.

Please change the underlying http-client

Comments (4)

  1. Yavor Vasilev

    Could you elaborate on the “we are overriding the kubernetes-clusters tls certificate”?

    Do you set your own trust store for client HTTPS connections?

    Do you use the OIDC SDK directly or via some higher level framework / lib?

  2. Pascal Knüppel reporter

    we are using it directly. This is our code:

    HTTPRequest discoveryRequest = new OIDCProviderConfigurationRequest(issuer).toHTTPRequest();
    discoveryRequest.setSSLSocketFactory(sslSocketFactory);
    discoveryRequest.setHostnameVerifier(hostnameVerifier);
    
    OIDCProviderMetadata opMetadata;
    try
    {
      log.trace("Loading OpenID Provider Metadata from discovery endpoint: {}{}", oidcBaseUrl, wellKnownPath);
      HTTPResponse discoveryResponse = discoveryRequest.send();
      opMetadata = OIDCProviderMetadata.parse(discoveryResponse.getContentAsJSONObject());
    }
    

    So we are instantiating the truststore also manually. It must be configured by properties before using the application.

    The kubernetes config is set like this:

    kind: Ingress
    apiVersion: networking.k8s.io/v1
    metadata:
      name: my-keycloak
    spec:
      tls:
        - hosts:
            - my-keycloak
          secretName: my-keycloak-tls-secret
      rules:
        - host: my-keycloak
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: my-keycloak
                    port:
                      number: 80
    

    We are using a certificate especially for the keycloak instance and not the ingress main certificate.

    Now that I know what is happening I am able to work around this. But I just thought the HTTPSUrlConnection simply would not support it instead of being a bug.

    Thx for letting me know.

  3. Vladimir Dzhuvinov

    Hi Pascal,

    If the work around mentioned in the cited Java issue doesn’t help please write here.

    In the meantime we’ll try to find out more about this SNI issue and file a ticket with Java if necessary.

  4. Log in to comment