Java WebSocket get distinguished name of client - java

I have a Java WebSocket server running on GlassFish, and users are to connect using client TLS certificates that we give them. The distinguished name from the certificate is what we used to identify the user. Once a connection has been made to a ServerEndpoint, my #OnOpen method is called and given a Session object.
I can tell if session.isSecure(), but nothing more than that. The Session object gives me no visibility into the properties of the TLS connection. How do I fetch the distinguished name of a client when they're connected via WebSocket?

I believe you can only do that in the websocket handshake (see here for an idea).
Websocket are "upgraded" from a HTTP request and the details of the request are available only during that upgrade request. You could try to extract the user principal from the HandshakeRequest, which normally should get you a X500Principal.

Related

ERR_CERT_AUTHORITY_INVALID when accessing same hostname with different port

We have a splunk instance which is exposed to internet via say https://splunk.mycompany.com
When we access the above URL browser says connection is secure meaning all certificates are ok.
Now splunk REST API service is running on port 8089. So to access splunk REST API we have to hit
https://splunk.mycompany.com:8089
Whenever we are hitting the above URL we are getting certificate issues and browser is saying "your connection is not private"
Error is: NET::ERR_CERT_AUTHORITY_INVALID
As I am still accessing the same hostname via https (and a new port) it should establish a secure connection. But why it's failing to validate certificate authority?
Edit: I have been told by the splunk team to take ther certificate of https://splunk.mycompany.com and install in the java keystore in the machine from where the REST API call is being made. They also told this is working for otheres. My question why it is even needed?
You should enable SSL on port 8089 via server.conf file.
Have a look at the Splunk Documentation here: https://docs.splunk.com/Documentation/Splunk/9.0.0/Security/ConfigTLSCertsS2S

SSL client (Java) is not sending a certificate back to the server in two-way SSL handshake

We are trying to access a restful web service resource hosted on IIS server with https protocol.
When we disable TWO WAY SSL Auth (server side validation of client certificate disabled) everything works fine.
When the IIS imposes TWO WAY SSL (server side validation of client certificate enabled) we are getting the below exception:
403 - Forbidden: Access is denied.
You do not have permission to view this directory or page using the credentials that you supplied.
We are using java 1.8 update 102, IIS server 7.5 and TLS 1.2 for ssl
For detailed issue please open the below link:
For details SSL Debug log, certificates, client program
It will be great help if someone help us.
Thanks!
See this warning in the SSL log:
no suitable certificate found - continuing without client authentication
Your server is sending a list of accepted CAs to request a client certificate, but your client does not find a suitable one. It seems your keystore has the correct certificate. Ensure that your certificate is correct, for example installing it in the browser and navigating to a protected resource
May be it is a configuration issue of your Java client. Please read HttpClientBuilder documentation carefully
System properties will be taken into account when configuring the default implementations when useSystemProperties() method is called prior to calling build().
You did not call useSystemProperties().
See also this bug report that might affect you https://issues.apache.org/jira/plugins/servlet/mobile#issue/HTTPCLIENT-1477

How to test connection to server SSL port via proxy using Apache HttpClient 4.3.4?

I'm trying to validate an SSL connection to an http server through a proxy server. In my case, I have 4 pieces of information which are all supplied by the user, and which I'd like to validate explicitly: target host, target port, proxy host, proxy port. I'd prefer to NOT make an actual HTTP request in order to do this validation, since that requires 2 more pieces of information: a request method, and a path (ie. "GET /"). I'd really like to be able to use the HttpClient library because it supports NTLM proxy auth.
I suppose what I want is to get the response of a CONNECT request sent to the proxy server, as all it requires are the 4 pieces of information I have (plus any proxy creds). However this seems to be an implicit request, the result of which is not available to the library client (unless it returns a 407 status code). Is there some way to trigger the CONNECT request explicitly?
You can use ProxyClient shipped with Apache HttpClient. It does precisely that.

Need a method to pass client IP through my Apache httpd proxy for Tomcat getRemoteAddr() [duplicate]

To obtain the client IP address in my ASP.NET application I've used the X-Forwarded-For, and get the first IP address from the list (accordingly to the information I've found, there is a client, proxy1, proxy2..). But I've heard recently that it is better to get this information from X-Forwarded-IP header because the client IP address in X-Forwarded-For can be modified by proxy, what is the difference, and which one address should I use?
X-Forwarded-For is the conventional way of identifying the originating IP address of the user connecting to the web server coming from either a HTTP proxy, load balancer.
X-Forwarded-IP is the conventional way of identifying the originating IP address of the user connecting to the email server through an HTTP mail service.
X-Forwarded-For is a non-standard header, introduced originally by Squid. It is a proxy- specific header, that helps a server identify the original requestor of a call that did pass-through the proxy - so obviously any proxy on the request path should/will modify X-Forwarded-For. Without proxy on the request path, this header shouldn't even be in the request.
Because this header is non-standard, there is no guarantee you'll get it, and the way it is handled can differ on the proxy implementation. You have no guarantee either that it will contain a proper IP.
Since 2014, the IETF has approved a standard header definition for proxy, called "Forwarded", documented here https://www.rfc-editor.org/rfc/rfc7239 that should be use instead of X-Forwarded headers. This is the one you should use reliably to get originating IP in case your request is handled by a proxy.
In general, the proxy headers (Forwarded or X-Forwarded-For) are the right way to get your client IP only when you are sure they come to you via a proxy. If there is no proxy header or no usable value in, you should default to the REMOTE_ADDR server variable.

Handling password updates in Java SSL

I have a client-server java application, where communication happens over SSL. Right now I am generating keypairs by hand, but I need a programmatic system for key management.
The server maintains a user database, and on the client side I do not want to store a copy of the password. Somehow the client will log in to the server using a password. If the password is correct, the server and client will set up keys. From then on they can use those keys and not have to use the password. This brings me to my first question:
When the user enters the password the first time, how do I encrypt that transmission? Because there will be no keys and thus no SSL at this point.
Then there is the issue of the user changing their password. The idea is they will go through a web interface to change their password on the server. Then the next time a client connects, their old keys should not work and they should be asked to enter the new password. Which brings me to my next question:
What is the best practice for
handling the password change when
dealing with SSL?
I can just delete the server side key when they change their password. Then the client wont be able to communicate, and then I can have the client ask for a new password. But it seems a little kludgey.
While an SSL connection can authenticate the client using a client-side certificate, it's most often used only to authenticate the server and to create an encrypted connection between an identified server (by virtue of a certificate tied to a domain name), and an anonymous client.
To use client certificates the client must generate the PKCS key-pair, a certificate signing request and get it signed by an authority that the server trusts. Absent that process, authentication of the client is typically done be a protocol on top of SSL which requires some secret that only the client knows. This is typically a password, such as a good ol' website login.
Conversely, what you are describing is actually a machine generated ephemeral (out of thin air) password (these are often called "keys", but it's important that you understand it's really just a special password). That is, after an initial connection authenticated with a password typed by the user, you send the client an ephemeral password to store and use for subsequent connections.
To handle password change, you simply need to change your protocol to allow the ephemeral password. If it's not correct but the server has one, you might want to lock the account, assuming a hack attempt (though that can be a DoS opening). Otherwise, if it's not correct because the server has no ephemeral key (i.e. the server side has blanked it because the password was changed), then you simple send a response to the client to challenge the user for the current password. The user then enters the password, and assuming it matches, the server then generates and transmits a new ephemeral password.
EDIT: To clarify, even though your are generating PKCS key-pairs, without doing that client-side and binding them into a certificate, this is not client-side certificate authentication. It's merely a cryptographically strong machine generated ephemeral password.
And, beware, that at the end of the day, your system is only as strong as the initial password which caused the key-pair to be generated (or, subsequently, replaced).
You still can have SSL between client and server. In fact, you should.
The server won't be able to trust the client yet. Client can trust the server, because the server certificate is available to the client.
For example, look how most logins on web are implemented: you are not authenticated yet, but you're going into HTTPS. This is one-way SSL. Client is using a temporal key. Password is passed over the encrypted connection. This protects from eavesdropping.
When the mutual trust (through validation of the password) is established, you can pass client certificate over the same connection and reset the session. From that moment you'll have a two-way SSL, a mutual trust.
UPDATE
I see a bit of confusion in the thread due to not clear wording of "requirements". Let me write down the collaboration between client and server:
Session 1:
Client needs to talk to server
Client generates a temporal pair of private and public key
Client connects to server via SSL and passes public key to server for the session
Client receives server public key/certificate and compares it to one it knows a priori; bail out if mismatched.
One-way SSL connection has been established at this point; client knows for sure it talks to server, while server doesn't know the identity of the client. The connection is encrypted though.
Client passes in credentials (userid and password, likely).
Server validates them and bails out if they do not match.
Server now trusts the client is, say, John Smith from Nebraska.
Client asks server to store current public key as client permanent public key OR generates another key pair and sends the public one to server (I do not see a problem to use the same key, but I may be overlooking something).
End of session.
Session 2:
Client connects to server over SSL
Client provides its public key/certificate
Server compares it to the one stored on server side
Server provides its public key/certificate
Client compares it to the known one.
Mutual trust has been established, connection is encrypted, server knows the client is John Smith from Nebraska.
Still, to be on the safe side, server may still request John to enter the password.
Since using SSL for client authentication requires keys to already be shared, you have two choices: either don't use SSL to provide client authentication, or renegotiate after delivering the client certificate to the client.
In the first model, on first connection, the client first connects over SSL with no client auth, then issues a login command of some sort, and receives a session token. At that point, the server knows that the other party on that SSL connection is that particular user. If the client wishes to reconnect later, it just present that session token to authenticate itself at the start of that second connection (still over SSL, but not using client auth). In this model, revocation of sessions can be done by deleting the server's notion of the session.
In the second model, the the server responds to the login command by providing a client cert that it signs. From there, the client will renegotiate the connection using the new certificate. In this model, revocation can be done by using something akin to a certificate revocation list (keep this from growing too big by using moderate expirations on the certificates).

Categories