Skip to content

Commit 889d79d

Browse files
author
kasemir
committed
Get client's cert status PV name into TLSHandshakeInfo
1 parent bf91b37 commit 889d79d

File tree

3 files changed

+45
-31
lines changed

3 files changed

+45
-31
lines changed

core/pva/src/main/java/org/epics/pva/common/SecureSockets.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,14 @@ public static class TLSHandshakeInfo
276276
/** Host of the peer */
277277
public String hostname;
278278

279+
/** PV for client certificate status */
280+
public String status_pv_name;
281+
282+
@Override
283+
public String toString()
284+
{
285+
return "Name " + name + ", host " + hostname + ", cert status PV " + status_pv_name;
286+
}
279287

280288
/** Get TLS/SSH info from socket
281289
* @param socket {@link SSLSocket}
@@ -296,9 +304,40 @@ public static TLSHandshakeInfo fromSocket(final SSLSocket socket) throws Excepti
296304

297305
try
298306
{
307+
// Log certificate chain, grep cert status PV name
308+
String status_pv_name = "";
309+
final SSLSession session = socket.getSession();
310+
logger.log(Level.FINER, "Client name: '" + SecureSockets.getPrincipalCN(session.getPeerPrincipal()) + "'");
311+
for (Certificate cert : session.getPeerCertificates())
312+
if (cert instanceof X509Certificate x509)
313+
{
314+
// Is this the cert for the client principal, or one of the authorities?
315+
boolean is_principal_cert = false;
316+
317+
logger.log(Level.FINER, "* " + x509.getSubjectX500Principal());
318+
if (session.getPeerPrincipal().equals(x509.getSubjectX500Principal()))
319+
{
320+
logger.log(Level.FINER, " - Client CN");
321+
is_principal_cert = true;
322+
}
323+
if (x509.getBasicConstraints() >= 0)
324+
logger.log(Level.FINER, " - Certificate Authority");
325+
logger.log(Level.FINER, " - Expires " + x509.getNotAfter());
326+
if (x509.getSubjectX500Principal().equals(x509.getIssuerX500Principal()))
327+
logger.log(Level.FINER, " - Self-signed");
328+
329+
byte[] value = x509.getExtensionValue("1.3.6.1.4.1.37427.1");
330+
String pv_name = SecureSockets.decodeDERString(value);
331+
logger.log(Level.FINER, " - Status PV: " + pv_name);
332+
333+
if (is_principal_cert && pv_name != null && !pv_name.isBlank())
334+
status_pv_name = pv_name;
335+
}
336+
337+
299338
// No way to check if there is peer info (certificates, principal, ...)
300339
// other then success vs. exception..
301-
final Principal principal = socket.getSession().getPeerPrincipal();
340+
final Principal principal = session.getPeerPrincipal();
302341
String name = getPrincipalCN(principal);
303342
if (name == null)
304343
{
@@ -309,6 +348,7 @@ public static TLSHandshakeInfo fromSocket(final SSLSocket socket) throws Excepti
309348
final TLSHandshakeInfo info = new TLSHandshakeInfo();
310349
info.name = name;
311350
info.hostname = socket.getInetAddress().getHostName();
351+
info.status_pv_name = status_pv_name;
312352

313353
return info;
314354
}

core/pva/src/main/java/org/epics/pva/server/ServerTCPHandler.java

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,14 @@
1212
import java.net.InetSocketAddress;
1313
import java.net.Socket;
1414
import java.nio.ByteBuffer;
15-
import java.security.cert.Certificate;
16-
import java.security.cert.X509Certificate;
1715
import java.util.Objects;
1816
import java.util.logging.Level;
1917

20-
import javax.net.ssl.SSLSession;
21-
import javax.net.ssl.SSLSocket;
22-
2318
import org.epics.pva.common.CommandHandlers;
2419
import org.epics.pva.common.PVAAuth;
2520
import org.epics.pva.common.PVAHeader;
2621
import org.epics.pva.common.RequestEncoder;
2722
import org.epics.pva.common.SearchResponse;
28-
import org.epics.pva.common.SecureSockets;
2923
import org.epics.pva.common.SecureSockets.TLSHandshakeInfo;
3024
import org.epics.pva.common.TCPHandler;
3125
import org.epics.pva.data.PVASize;
@@ -74,30 +68,6 @@ public ServerTCPHandler(final PVAServer server, final Socket client, final TLSHa
7468
this.server = Objects.requireNonNull(server);
7569
this.tls_info = tls_info;
7670

77-
// Log client's security info
78-
if (tls_info != null &&
79-
client instanceof SSLSocket socket &&
80-
logger.isLoggable(Level.FINE))
81-
{
82-
final SSLSession session = socket.getSession();
83-
logger.log(Level.FINE, "Client name: '" + SecureSockets.getPrincipalCN(session.getPeerPrincipal()) + "'");
84-
for (Certificate cert : session.getPeerCertificates())
85-
if (cert instanceof X509Certificate x509)
86-
{
87-
logger.log(Level.FINE, "* " + x509.getSubjectX500Principal());
88-
if (session.getPeerPrincipal().equals(x509.getSubjectX500Principal()))
89-
logger.log(Level.FINE, " - Client CN");
90-
if (x509.getBasicConstraints() >= 0)
91-
logger.log(Level.FINE, " - Certificate Authority");
92-
logger.log(Level.FINE, " - Expires " + x509.getNotAfter());
93-
if (x509.getSubjectX500Principal().equals(x509.getIssuerX500Principal()))
94-
logger.log(Level.FINE, " - Self-signed");
95-
96-
byte[] value = x509.getExtensionValue("1.3.6.1.4.1.37427.1");
97-
logger.log(Level.FINE, " - Status PV: " + SecureSockets.decodeDERString(value));
98-
}
99-
}
100-
10171
server.register(this);
10272
startReceiver();
10373
startSender();

core/pva/src/main/java/org/epics/pva/server/ServerTCPListener.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ private void listen()
228228
try
229229
{
230230
tls_info = TLSHandshakeInfo.fromSocket((SSLSocket) client);
231+
logger.log(Level.FINE, "Client TLS info: " + tls_info);
232+
// TODO Monitor status PV, close connection when PV shows expired/revoked cert
233+
// if (! tls_info.status_pv_name.isEmpty() /* && PVASettings.CHECK_CERT_STATUS */)
234+
// logger.log(Level.INFO, "Should check " + tls_info.status_pv_name);
231235
}
232236
catch (SSLHandshakeException ssl)
233237
{

0 commit comments

Comments
 (0)