Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -67,12 +67,13 @@ public static void logTLSHandshakeEvent(Instant start,
int peerPort,
String cipherSuite,
String protocolVersion,
String namedGroup,
long peerCertId) {
assert securityLogger != null;
String prepend = getDurationString(start);
securityLogger.log(LOG_LEVEL, prepend +
" TLSHandshake: {0}:{1,number,#}, {2}, {3}, {4,number,#}",
peerHost, peerPort, protocolVersion, cipherSuite, peerCertId);
" TLSHandshake: {0}:{1,number,#}, {2}, {3}, {4}, {5,number,#}",
peerHost, peerPort, protocolVersion, cipherSuite, namedGroup, peerCertId);
}

public static void logSecurityPropertyEvent(String key,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -35,4 +35,5 @@ public final class TLSHandshakeEvent extends Event {
public String protocolVersion;
public String cipherSuite;
public long certificateId;
public String namedGroup;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: namedGroup is being logged right after cipherSuite, it will be consistent to keep the same order here and in src/jdk.jfr/share/classes/jdk/jfr/events/TLSHandshakeEvent.java

}
22 changes: 16 additions & 6 deletions src/java.base/share/classes/sun/security/ssl/Finished.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -562,7 +562,7 @@ private void onConsumeFinished(ClientHandshakeContext chc,

// handshake context cleanup.
chc.handshakeFinished = true;
recordEvent(chc.conContext.conSession);
recordEvent(chc);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We record an event both on consuming and on producing Finished:

  • Would there be any difference between those 2 events? AFAICT all the event's fields should be equal.
  • How do we differentiate between consuming and producing events?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, I see now that we actually log only once on each side: client producing and server consuming.


// May need to retransmit the last flight for DTLS.
if (!chc.sslContext.isDTLS()) {
Expand Down Expand Up @@ -623,7 +623,7 @@ private void onConsumeFinished(ServerHandshakeContext shc,

// handshake context cleanup.
shc.handshakeFinished = true;
recordEvent(shc.conContext.conSession);
recordEvent(shc);

// May need to retransmit the last flight for DTLS.
if (!shc.sslContext.isDTLS()) {
Expand Down Expand Up @@ -765,7 +765,7 @@ private byte[] onProduceFinished(ClientHandshakeContext chc,
// handshake context cleanup.
chc.handshakeFinished = true;
chc.conContext.finishHandshake();
recordEvent(chc.conContext.conSession);
recordEvent(chc);


// The handshake message has been delivered.
Expand Down Expand Up @@ -1164,7 +1164,7 @@ private void onConsumeFinished(ServerHandshakeContext shc,
if (!shc.sslContext.isDTLS()) {
shc.conContext.finishHandshake();
}
recordEvent(shc.conContext.conSession);
recordEvent(shc);

//
// produce
Expand All @@ -1174,9 +1174,10 @@ private void onConsumeFinished(ServerHandshakeContext shc,
}
}

private static void recordEvent(SSLSessionImpl session) {
private static void recordEvent(HandshakeContext hc) {
TLSHandshakeEvent event = new TLSHandshakeEvent();
if (event.shouldCommit() || EventHelper.isLoggingSecurity()) {
SSLSessionImpl session = hc.conContext.conSession;
int hash = 0;
try {
// use hash code for Id
Expand All @@ -1187,12 +1188,20 @@ private static void recordEvent(SSLSessionImpl session) {
// not verified msg
}
long peerCertificateId = Integer.toUnsignedLong(hash);
String namedGroup = "N/A";
for (SSLCredentials cred : hc.handshakeCredentials) {
if (cred instanceof NamedGroupCredentials ngCred) {
namedGroup = ngCred.getNamedGroup().name;
break;
}
}
if (event.shouldCommit()) {
event.peerHost = session.getPeerHost();
event.peerPort = session.getPeerPort();
event.cipherSuite = session.getCipherSuite();
event.protocolVersion = session.getProtocol();
event.certificateId = peerCertificateId;
event.namedGroup = namedGroup;
event.commit();
}
if (EventHelper.isLoggingSecurity()) {
Expand All @@ -1201,6 +1210,7 @@ private static void recordEvent(SSLSessionImpl session) {
session.getPeerPort(),
session.getCipherSuite(),
session.getProtocol(),
namedGroup,
peerCertificateId);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -57,4 +57,7 @@ public final class TLSHandshakeEvent extends MirrorEvent {
@CertificateId
@Unsigned
public long certificateId;

@Label("Named Group")
public String namedGroup;
}
55 changes: 41 additions & 14 deletions test/jdk/jdk/jfr/event/security/TestTLSHandshakeEvent.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -30,39 +30,66 @@
import jdk.test.lib.jfr.EventNames;
import jdk.test.lib.jfr.Events;
import jdk.test.lib.security.TestTLSHandshake;
import jdk.test.lib.security.SecurityUtils;

/*
* @test
* @bug 8148188
* @bug 8148188 8301626
* @summary Enhance the security libraries to record events of interest
* @requires vm.flagless
* @requires vm.hasJFR
* @library /test/lib
* @run main/othervm jdk.jfr.event.security.TestTLSHandshakeEvent
*/
public class TestTLSHandshakeEvent {
record TLSConfig(String protocol, String cipherSuite, String namedGroup,
long certId) {};

private static final List<TLSConfig> CONFIGS = List.of(
new TLSConfig("TLSv1.3", "TLS_AES_256_GCM_SHA384", "X25519MLKEM768",
3237675498l),
new TLSConfig("TLSv1.3", "TLS_CHACHA20_POLY1305_SHA256",
"X25519MLKEM768", 3237675498l),
new TLSConfig("TLSv1.2", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"secp256r1", 3237675498l),
new TLSConfig("TLSv1.2", "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
"ffdhe2048", 3188175476l),
new TLSConfig("TLSv1.2", "TLS_RSA_WITH_AES_256_CBC_SHA",
"N/A", 3010289526l)
);

public static void main(String[] args) throws Exception {
try (Recording recording = new Recording()) {
recording.enable(EventNames.TLSHandshake).withStackTrace();
recording.start();
TestTLSHandshake handshake = new TestTLSHandshake();
handshake.run();
recording.stop();
// re-enable TLS_RSA suites as one test depends on it
SecurityUtils.removeFromDisabledTlsAlgs("TLS_RSA_*");
for (TLSConfig config : CONFIGS) {
System.out.println(config);
try (Recording recording = new Recording()) {
recording.enable(EventNames.TLSHandshake).withStackTrace();
recording.start();
TestTLSHandshake handshake = new TestTLSHandshake();
handshake.protocolVersion = config.protocol();
handshake.cipherSuite = config.cipherSuite();
handshake.namedGroup = config.namedGroup();
handshake.run();
recording.stop();

List<RecordedEvent> events = Events.fromRecording(recording);
Events.hasEvents(events);
assertEvent(events, handshake);
List<RecordedEvent> events = Events.fromRecording(recording);
Events.hasEvents(events);
assertEvent(events, handshake, config);
}
}
}

private static void assertEvent(List<RecordedEvent> events, TestTLSHandshake handshake) throws Exception {
private static void assertEvent(List<RecordedEvent> events,
TestTLSHandshake handshake, TLSConfig config) throws Exception {
System.out.println(events);
for (RecordedEvent e : events) {
if (handshake.peerHost.equals(e.getString("peerHost"))) {
Events.assertField(e, "peerPort").equal(handshake.peerPort);
Events.assertField(e, "protocolVersion").equal(handshake.protocolVersion);
Events.assertField(e, "certificateId").equal(TestTLSHandshake.CERT_ID);
Events.assertField(e, "cipherSuite").equal(TestTLSHandshake.CIPHER_SUITE);
Events.assertField(e, "certificateId").equal(config.certId());
Events.assertField(e, "cipherSuite").equal(handshake.cipherSuite);
Events.assertField(e, "namedGroup").equal(handshake.namedGroup);
var method = e.getStackTrace().getFrames().get(0).getMethod();
if (method.getName().equals("recordEvent")) {
throw new Exception("Didn't expected recordEvent as top frame");
Expand Down
22 changes: 17 additions & 5 deletions test/jdk/jdk/security/logging/TestTLSHandshakeLog.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -27,13 +27,20 @@

/*
* @test
* @bug 8148188
* @bug 8148188 8301626
* @summary Enhance the security libraries to record events of interest
* @library /test/lib /test/jdk
* @run main/othervm jdk.security.logging.TestTLSHandshakeLog LOGGING_ENABLED
* @run main/othervm jdk.security.logging.TestTLSHandshakeLog LOGGING_DISABLED
*/
public class TestTLSHandshakeLog {
record TLSConfig(String protocol, String cipherSuite, String namedGroup) {};

private static TLSConfig CONFIG =
new TLSConfig("TLSv1.2",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"secp256r1");

public static void main(String[] args) throws Exception {
LogJvm l = new LogJvm(TLSHandshake.class, args);
l.addExpected("FINE: X509Certificate: Alg:SHA256withRSA, Serial:" + TestTLSHandshake.CERT_SERIAL);
Expand All @@ -44,15 +51,20 @@ public static void main(String[] args) throws Exception {
", " + TestTLSHandshake.CERT_ID);
l.addExpected("SunJSSE Test Serivce");
l.addExpected("TLSHandshake:");
l.addExpected("TLSv1.2");
l.addExpected(TestTLSHandshake.CIPHER_SUITE +", " + TestTLSHandshake.CERT_ID);
l.addExpected(CONFIG.protocol());
l.addExpected(CONFIG.cipherSuite());
l.addExpected(CONFIG.namedGroup());
l.addExpected(Long.toString(TestTLSHandshake.CERT_ID));
l.testExpected();
}

public static class TLSHandshake {
public static void main(String[] args) throws Exception {
TestTLSHandshake handshake = new TestTLSHandshake();
handshake.protocolVersion = CONFIG.protocol();
handshake.cipherSuite = CONFIG.cipherSuite();
handshake.namedGroup = CONFIG.namedGroup();
handshake.run();
}
}
}
}
21 changes: 16 additions & 5 deletions test/lib/jdk/test/lib/security/TestTLSHandshake.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -25,14 +25,12 @@

import java.io.*;

import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;


public final class TestTLSHandshake extends SSLSocketTest {

public static final String CIPHER_SUITE =
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
public static final long CERT_ID = Integer.toUnsignedLong(-1057291798);
public static final long ANCHOR_CERT_ID = Integer.toUnsignedLong(1688661792);
public static final String CERT_SERIAL = "00:ed:be:c8:f7:05:af:25:14";
Expand All @@ -41,6 +39,8 @@ public final class TestTLSHandshake extends SSLSocketTest {
public String protocolVersion;
public String peerHost;
public int peerPort;
public String cipherSuite;
public String namedGroup;

@Override
protected void runServerApplication(SSLSocket socket) throws Exception {
Expand All @@ -54,7 +54,17 @@ protected void runServerApplication(SSLSocket socket) throws Exception {

@Override
protected void runClientApplication(SSLSocket socket) throws Exception {
socket.setEnabledCipherSuites(new String[] { CIPHER_SUITE });
SSLParameters params = socket.getSSLParameters();
if (protocolVersion != null) {
params.setProtocols(new String [] { protocolVersion });
}
if (cipherSuite != null) {
params.setCipherSuites(new String[] { cipherSuite });
}
if (namedGroup != null) {
params.setNamedGroups(new String[] { namedGroup });
}
socket.setSSLParameters(params);
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();

Expand All @@ -66,5 +76,6 @@ protected void runClientApplication(SSLSocket socket) throws Exception {
protocolVersion = sslSession.getProtocol();
peerHost = sslSession.getPeerHost();
peerPort = sslSession.getPeerPort();
cipherSuite = sslSession.getCipherSuite();
}
}