Skip to content

Commit 87b809a

Browse files
committed
8296229: JFR: jfr tool should print unsigned values correctly
Reviewed-by: coffeys, mgronlun
1 parent e7c2a8e commit 87b809a

File tree

15 files changed

+76
-40
lines changed

15 files changed

+76
-40
lines changed

src/java.base/share/classes/jdk/internal/event/EventHelper.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
3434
import java.time.Instant;
3535
import java.util.Date;
3636
import java.util.stream.Collectors;
37-
import java.util.stream.IntStream;
37+
import java.util.stream.LongStream;
3838

3939
/**
4040
* A helper class to have events logged to a JDK Event Logger.
@@ -82,11 +82,11 @@ public static void logSecurityPropertyEvent(String key,
8282
"SecurityPropertyModification: key:{0}, value:{1}", key, value);
8383
}
8484

85-
public static void logX509ValidationEvent(int anchorCertId,
86-
int[] certIds) {
85+
public static void logX509ValidationEvent(long anchorCertId,
86+
long[] certIds) {
8787
assert securityLogger != null;
88-
String codes = IntStream.of(certIds)
89-
.mapToObj(Integer::toString)
88+
String codes = LongStream.of(certIds)
89+
.mapToObj(Long::toString)
9090
.collect(Collectors.joining(", "));
9191
securityLogger.log(LOG_LEVEL,
9292
"ValidationChain: {0,number,#}, {1}", anchorCertId, codes);

src/java.base/share/classes/sun/security/jca/JCAUtil.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public static void tryCommitCertEvent(Certificate cert) {
110110
String keyType = pKey.getAlgorithm();
111111
int length = KeyUtil.getKeySize(pKey);
112112
int hashCode = x509.hashCode();
113+
long certifcateId = Integer.toUnsignedLong(hashCode);
113114
long beginDate = x509.getNotBefore().getTime();
114115
long endDate = x509.getNotAfter().getTime();
115116
if (X509CertificateEvent.isTurnedOn()) {
@@ -120,7 +121,7 @@ public static void tryCommitCertEvent(Certificate cert) {
120121
xce.issuer = issuer;
121122
xce.keyType = keyType;
122123
xce.keyLength = length;
123-
xce.certificateId = hashCode;
124+
xce.certificateId = certifcateId;
124125
xce.validFrom = beginDate;
125126
xce.validUntil = endDate;
126127
xce.commit();
@@ -132,7 +133,7 @@ public static void tryCommitCertEvent(Certificate cert) {
132133
issuer,
133134
keyType,
134135
length,
135-
hashCode,
136+
certifcateId,
136137
beginDate,
137138
endDate);
138139
}

src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -227,23 +227,24 @@ private static PKIXCertPathValidatorResult validate(TrustAnchor anchor,
227227

228228
X509ValidationEvent xve = new X509ValidationEvent();
229229
if (xve.shouldCommit() || EventHelper.isLoggingSecurity()) {
230-
int[] certIds = params.certificates().stream()
230+
long[] certIds = params.certificates().stream()
231231
.mapToInt(Certificate::hashCode)
232+
.mapToLong(Integer::toUnsignedLong)
232233
.toArray();
233-
int anchorCertId = (anchorCert != null) ?
234+
int hash = (anchorCert != null) ?
234235
anchorCert.hashCode() : anchor.getCAPublicKey().hashCode();
236+
long anchorCertId = Integer.toUnsignedLong(hash);
235237
if (xve.shouldCommit()) {
236238
xve.certificateId = anchorCertId;
237239
int certificatePos = 1; // most trusted CA
238240
xve.certificatePosition = certificatePos;
239241
xve.validationCounter = validationCounter.incrementAndGet();
240242
xve.commit();
241243
// now, iterate through remaining
242-
for (int id : certIds) {
244+
for (long id : certIds) {
243245
xve.certificateId = id;
244246
xve.certificatePosition = ++certificatePos;
245247
xve.commit();
246-
247248
}
248249
}
249250
if (EventHelper.isLoggingSecurity()) {

src/java.base/share/classes/sun/security/ssl/Finished.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1146,15 +1146,16 @@ private void onConsumeFinished(ServerHandshakeContext shc,
11461146
private static void recordEvent(SSLSessionImpl session) {
11471147
TLSHandshakeEvent event = new TLSHandshakeEvent();
11481148
if (event.shouldCommit() || EventHelper.isLoggingSecurity()) {
1149-
int peerCertificateId = 0;
1149+
int hash = 0;
11501150
try {
11511151
// use hash code for Id
1152-
peerCertificateId = session
1152+
hash = session
11531153
.getCertificateChain()[0]
11541154
.hashCode();
11551155
} catch (SSLPeerUnverifiedException e) {
11561156
// not verified msg
11571157
}
1158+
long peerCertificateId = Integer.toUnsignedLong(hash);
11581159
if (event.shouldCommit()) {
11591160
event.peerHost = session.getPeerHost();
11601161
event.peerPort = session.getPeerPort();

src/jdk.jfr/share/classes/jdk/jfr/events/TLSHandshakeEvent.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
2929
import jdk.jfr.Description;
3030
import jdk.jfr.Label;
3131
import jdk.jfr.Name;
32+
import jdk.jfr.Unsigned;
3233
import jdk.jfr.internal.MirrorEvent;
3334

3435
@Category({"Java Development Kit", "Security"})
@@ -52,5 +53,6 @@ public final class TLSHandshakeEvent extends AbstractJDKEvent {
5253
@Label("Certificate Id")
5354
@Description("Peer Certificate Id")
5455
@CertificateId
56+
@Unsigned
5557
public long certificateId;
5658
}

src/jdk.jfr/share/classes/jdk/jfr/events/X509CertificateEvent.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@ public final class X509CertificateEvent extends AbstractJDKEvent {
5454

5555
@Label("Certificate Id")
5656
@CertificateId
57+
@Unsigned
5758
public long certificateId;
5859

5960
@Label("Valid From")

src/jdk.jfr/share/classes/jdk/jfr/events/X509ValidationEvent.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
3636
public final class X509ValidationEvent extends AbstractJDKEvent {
3737
@CertificateId
3838
@Label("Certificate Id")
39+
@Unsigned
3940
public long certificateId;
4041

4142
@Label("Certificate Position")

src/jdk.jfr/share/classes/jdk/jfr/internal/tool/EventPrintWriter.java

+33-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
2828
import java.io.FileNotFoundException;
2929
import java.io.IOException;
3030
import java.io.PrintWriter;
31+
import java.math.BigInteger;
3132
import java.nio.file.Path;
3233
import java.util.ArrayList;
3334
import java.util.HashMap;
@@ -38,6 +39,7 @@
3839
import jdk.jfr.EventType;
3940
import jdk.jfr.Timespan;
4041
import jdk.jfr.Timestamp;
42+
import jdk.jfr.Unsigned;
4143
import jdk.jfr.ValueDescriptor;
4244
import jdk.jfr.consumer.RecordedEvent;
4345
import jdk.jfr.consumer.RecordedObject;
@@ -47,7 +49,7 @@
4749
abstract class EventPrintWriter extends StructuredWriter {
4850

4951
enum ValueType {
50-
TIMESPAN, TIMESTAMP, OTHER
52+
TIMESPAN, TIMESTAMP, UNSIGNED, OTHER
5153
}
5254

5355
protected static final String STACK_TRACE_FIELD = "stackTrace";
@@ -118,23 +120,44 @@ protected Object getValue(RecordedObject object, ValueDescriptor v) {
118120
valueType = determineValueType(v);
119121
typeOfValues.put(v, valueType);
120122
}
121-
switch (valueType) {
122-
case TIMESPAN:
123-
return object.getDuration(v.getName());
124-
case TIMESTAMP:
125-
return PRIVATE_ACCESS.getOffsetDataTime(object, v.getName());
126-
default:
127-
return object.getValue(v.getName());
123+
String name = v.getName();
124+
return switch (valueType) {
125+
case TIMESPAN -> object.getDuration(name);
126+
case TIMESTAMP -> PRIVATE_ACCESS.getOffsetDataTime(object, name);
127+
case UNSIGNED -> getUnsigned(object, name);
128+
case OTHER -> object.getValue(name);
129+
};
130+
}
131+
132+
private Object getUnsigned(RecordedObject object, String name) {
133+
// RecordedObject::getLong handles unsigned byte, short, int
134+
long value = object.getLong(name);
135+
// If unsigned long value exceeds 2^63, return (upper << 32) + lower
136+
if (value < 0) {
137+
int upper = (int) (value >>> 32);
138+
int lower = (int) value;
139+
BigInteger u = BigInteger.valueOf(Integer.toUnsignedLong(upper));
140+
u = u.shiftLeft(32);
141+
BigInteger l = BigInteger.valueOf(Integer.toUnsignedLong(lower));
142+
return u.add(l);
128143
}
144+
return Long.valueOf(value);
129145
}
130-
// It's expensive t check
146+
147+
// Somewhat expensive operation
131148
private ValueType determineValueType(ValueDescriptor v) {
132149
if (v.getAnnotation(Timespan.class) != null) {
133150
return ValueType.TIMESPAN;
134151
}
135152
if (v.getAnnotation(Timestamp.class) != null) {
136153
return ValueType.TIMESTAMP;
137154
}
155+
if (v.getAnnotation(Unsigned.class) != null) {
156+
return switch(v.getTypeName()) {
157+
case "byte", "short", "int", "long" -> ValueType.UNSIGNED;
158+
default -> ValueType.OTHER;
159+
};
160+
}
138161
return ValueType.OTHER;
139162
}
140163
}

test/jdk/jdk/jfr/event/security/TestTLSHandshakeEvent.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private static void assertEvent(List<RecordedEvent> events, TestTLSHandshake han
6161
if (handshake.peerHost.equals(e.getString("peerHost"))) {
6262
Events.assertField(e, "peerPort").equal(handshake.peerPort);
6363
Events.assertField(e, "protocolVersion").equal(handshake.protocolVersion);
64-
Events.assertField(e, "certificateId").equal(TestTLSHandshake.HASHCODE);
64+
Events.assertField(e, "certificateId").equal(TestTLSHandshake.CERT_ID);
6565
Events.assertField(e, "cipherSuite").equal(TestTLSHandshake.CIPHER_SUITE);
6666
return;
6767
}

test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,9 @@ private static void assertEvent3(List<RecordedEvent> events) throws Exception {
128128
switch (pos) {
129129
// use public key of cert provided in TrustAnchor
130130
case 1:
131-
Asserts.assertEquals(e.getLong("certificateId"),
132-
Long.valueOf(TestCertificate.ROOT_CA.certificate().getPublicKey().hashCode()));
131+
int hash = TestCertificate.ROOT_CA.certificate().getPublicKey().hashCode();
132+
Long id = Integer.toUnsignedLong(hash);
133+
Asserts.assertEquals(e.getLong("certificateId"), id);
133134
break;
134135
case 2:
135136
Events.assertField(e, "certificateId")

test/jdk/jdk/jfr/tool/TestPrintXML.java

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252

5353
import jdk.jfr.Timespan;
5454
import jdk.jfr.Timestamp;
55+
import jdk.jfr.Unsigned;
5556
import jdk.jfr.ValueDescriptor;
5657
import jdk.jfr.consumer.RecordedEvent;
5758
import jdk.jfr.consumer.RecordedObject;
@@ -149,6 +150,9 @@ static boolean compare(Object eventObject, Object xmlObject) {
149150
if (v.getAnnotation(Timespan.class) != null) {
150151
expectedValue = re.getDuration(name);
151152
}
153+
if (expectedValue instanceof Number && v.getAnnotation(Unsigned.class) != null) {
154+
expectedValue = Long.toUnsignedString(re.getLong(name));
155+
}
152156
if (!compare(expectedValue, xmlValue)) {
153157
return false;
154158
}

test/jdk/jdk/security/logging/TestTLSHandshakeLog.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ public static void main(String[] args) throws Exception {
4040
l.addExpected("Subject:CN=Regression Test");
4141
l.addExpected("Key type:EC, Length:256");
4242
l.addExpected("FINE: ValidationChain: " +
43-
TestTLSHandshake.ANCHOR_HASHCODE +
44-
", " + TestTLSHandshake.HASHCODE);
43+
TestTLSHandshake.ANCHOR_CERT_ID +
44+
", " + TestTLSHandshake.CERT_ID);
4545
l.addExpected("SunJSSE Test Serivce");
4646
l.addExpected("TLSHandshake:");
4747
l.addExpected("TLSv1.2");
48-
l.addExpected(TestTLSHandshake.CIPHER_SUITE +", " + TestTLSHandshake.HASHCODE);
48+
l.addExpected(TestTLSHandshake.CIPHER_SUITE +", " + TestTLSHandshake.CERT_ID);
4949
l.testExpected();
5050
}
5151

test/lib/jdk/test/lib/json/JSONValue.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323
package jdk.test.lib.json;
2424

25+
import java.math.BigInteger;
2526
import java.util.ArrayList;
2627
import java.util.HashMap;
2728
import java.util.Iterator;
@@ -317,7 +318,7 @@ private JSONValue parseNumber() {
317318

318319
var value = builder.toString();
319320
if (isInteger) {
320-
Long.parseLong(value);
321+
new BigInteger(value);
321322
return new JSONString(value);
322323
} else {
323324
Double.parseDouble(value);

test/lib/jdk/test/lib/security/TestCertificate.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,13 @@ public enum TestCertificate {
139139
public String encoded;
140140

141141
TestCertificate(String serialNumber, String subject, String issuer,
142-
long certId, String encoded) {
142+
int hash, String encoded) {
143143
this.serialNumber = serialNumber;
144144
this.subject = subject;
145145
this.issuer = issuer;
146146
this.algorithm = "SHA256withRSA";
147147
this.encoded = encoded;
148-
this.certId = certId;
148+
this.certId = Integer.toUnsignedLong(hash);
149149
this.keyType = "RSA";
150150
this.keyLength = 2048;
151151
}

test/lib/jdk/test/lib/security/TestTLSHandshake.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,8 @@ public final class TestTLSHandshake extends SSLSocketTest {
3333

3434
public static final String CIPHER_SUITE =
3535
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
36-
public static final long HASHCODE = -1057291798L;
37-
public static final long ANCHOR_HASHCODE = 1688661792L;
36+
public static final long CERT_ID = Integer.toUnsignedLong(-1057291798);
37+
public static final long ANCHOR_CERT_ID = Integer.toUnsignedLong(1688661792);
3838
public static final String CERT_SERIAL = "edbec8f705af2514";
3939
public static final String ANCHOR_CERT_SERIAL = "8e191778b2f331be";
4040

0 commit comments

Comments
 (0)