2

Getting sslhandshake exception with access denied error while invoking a GET call using spring boot Rest Template.

I am developing a java client to GET metrics from prometheus server. Creating a RestTemplate with basic authentication and sslContext with Tls1 ,1.1 & 1.2.

But getting the below exception when the GET call is invoked.

org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://a5faff994509b11e99f7d0285e129587-2110882066.us-east-1.elb.amazonaws.com/api/v1/query": Received fatal alert: access_denied; nested exception is javax.net.ssl.SSLHandshakeException: Received fatal alert: access_denied
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
    at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:311)
    at com.opscx.prometheus.PrometheusPocApplication.main(PrometheusPocApplication.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: access_denied
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:359)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:108)
    at com.opscx.prometheus.BasicAuthInterceptor.intercept(BasicAuthInterceptor.java:35)
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:92)
    at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:76)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
    ... 11 more

class org.springframework.web.client.ResourceAccessException

Tried debugging with -Djavax.net.debug=ssl:handshake:verbose but couldn't make out the issue.

Here is the out of the debug log

trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1542173365 bytes = { 177, 65, 144, 227, 154, 51, 246, 129, 182, 251, 188, 204, 134, 212, 156, 222, 208, 90, 86, 46, 87, 105, 16, 134, 146, 83, 144, 225 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension extended_master_secret
Extension server_name, server_name: [type=host_name (0), value=a5faff994509b11e99f7d0285e129587-2110882066.us-east-1.elb.amazonaws.com]
***
main, WRITE: TLSv1.2 Handshake, length = 273
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, access_denied
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: access_denied    

Here is my code

SSLContext sslContext = null;
        try {
            sslContext = SSLContextBuilder.create()
                    .loadTrustMaterial(null, (chain, authType) -> true)
                    .build();

        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }

        SSLConnectionSocketFactory sslConnectionSocketFactory =
                new SSLConnectionSocketFactory(sslContext,

                        new String[] { "TLSv1","TLSv1.1","TLSv1.2" },
                        //null,
                        null,
                        new LaxHostnameVerifier());

        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
                new PoolingHttpClientConnectionManager(RegistryBuilder.<ConnectionSocketFactory> create()
                        .register("http",
                                PlainConnectionSocketFactory.getSocketFactory())
                        .register("https",
                                sslConnectionSocketFactory)
                        .build());


        CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(poolingHttpClientConnectionManager).build();
        return httpClient;

I am creating an sslcontext with all three TLS protocols. The out put of the debug log is confusing to me.

    main, WRITE: TLSv1.2 Handshake, length = 273
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, access_denied

The clienthello is done with TLSV1.2, why is there a READ message of a TLSv1 alert ? and then strangely a RECV message of TLSv1.2 ALERT ?

If the server is able to send an alert with TLSv1.2 why don't it accept the handshake request ?

All the cipher suites are enabled and it should agree upon any one of the cipher. There are common ciphers both the sides.

The same code works with other REST based servers. I don't usually send a certificate with the call and it is supposed to work.

NOTE: The same code worked last night IST. It is strange that some time it works and sometimes it doesn't

I have spent more time on this and couldn't get enough answer of an access denied error. Would be great if anyone could give me some insights on this.

2 Answers2

1

The clienthello is done with TLSV1.2, why is there a READ message of a TLSv1 alert ? and then strangely a RECV message of TLSv1.2 ALERT ?

The server decided that it does not like this client. From the description of the TLS alwert:

access_denied
A valid certificate was received, but when access control was applied, the sender decided not to proceed with negotiation. This message is always fatal.

Thus, you need to check with the server provider of what the actual requirements of the server regarding the client are. It might for example that the client needs to provide a specific client certificate and that you've provided none or the wrong one.

Community
  • 1
  • 1
Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Should check with server provider as in the server i am trying to connect to ? And how is the same GET url work with Chrome ? I Tried with a self verified certificate as well. Is there a way to debug and understand what certificate chrome sends to this sever that makes it work ?? – Deepak Selvakumar May 28 '19 at 05:26
  • @DeepakSelvakumar: you can see from a packet capture (Wireshark) what certificates are sent as long as no TLS 1.3 is used yet. *"And how is the same GET url work with Chrome?"* - your question does not provide any information what the actual server requirements are and how Chrome is configured to match these, which means it is unknown what Chrome makes different that the server accepts the request. – Steffen Ullrich May 28 '19 at 06:08
  • Chrome is not configured with anything apart from default. Opening this URL gives a security warning about the certificate warning. Allowing to proceed asks the credentials and the result is received. I can install the wireshark and check the traffic, the certificates etc. How and what should i look for to check the requirements of a server ? thanks.. – Deepak Selvakumar May 28 '19 at 06:39
  • @DeepakSelvakumar: to get the requirements of the server you need to ask the ones who are responsible for the server, i.e. what kind of restrictions they have regarding the clients which can connect. – Steffen Ullrich May 28 '19 at 06:41
  • Strangely, the GET url works in my home network but not in the other network. I tried to compare the certificate issued in both the networks using Chrome dev tools and found that both the certificates are same. Only difference i see is at home network, the cipher used is different. It is ECDHE_RSA with P-256, and AES_128_GCM. whereas in the other network it is ECDHE_RSA, and AES_128_GCM. Does this make any difference ? – Deepak Selvakumar May 28 '19 at 16:24
  • @DeepakSelvakumar: it might be the relevant difference or it might be not. Again, the server decides if it does not like the client so you have to look at the server what restrictions are enforced there. – Steffen Ullrich May 28 '19 at 21:21
  • @SteffenUllrich Could you look at my question. I've been stuck since April. https://superuser.com/questions/1457978/handshake-failure-when-calling-service-in-websphere-on-my-local-computer – Philip Rego Jul 15 '19 at 18:03
0

I got this exact error message when a JRE generated by jlink was missing the jdk.crypto.ec module.

To include the module:
jlink --add-modules jdk.crypto.ec

Related answer

Asapha
  • 643
  • 8
  • 14