8296229: JFR: jfr tool should print unsigned values correctly

Reviewed-by: coffeys, mgronlun
This commit is contained in:
Erik Gahlin 2022-11-11 14:55:41 +00:00
parent e7c2a8e60e
commit 87b809a2cb
15 changed files with 77 additions and 41 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, 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
@ -34,7 +34,7 @@ import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
/**
* A helper class to have events logged to a JDK Event Logger.
@ -82,11 +82,11 @@ public final class EventHelper {
"SecurityPropertyModification: key:{0}, value:{1}", key, value);
}
public static void logX509ValidationEvent(int anchorCertId,
int[] certIds) {
public static void logX509ValidationEvent(long anchorCertId,
long[] certIds) {
assert securityLogger != null;
String codes = IntStream.of(certIds)
.mapToObj(Integer::toString)
String codes = LongStream.of(certIds)
.mapToObj(Long::toString)
.collect(Collectors.joining(", "));
securityLogger.log(LOG_LEVEL,
"ValidationChain: {0,number,#}, {1}", anchorCertId, codes);

View File

@ -110,6 +110,7 @@ public final class JCAUtil {
String keyType = pKey.getAlgorithm();
int length = KeyUtil.getKeySize(pKey);
int hashCode = x509.hashCode();
long certifcateId = Integer.toUnsignedLong(hashCode);
long beginDate = x509.getNotBefore().getTime();
long endDate = x509.getNotAfter().getTime();
if (X509CertificateEvent.isTurnedOn()) {
@ -120,7 +121,7 @@ public final class JCAUtil {
xce.issuer = issuer;
xce.keyType = keyType;
xce.keyLength = length;
xce.certificateId = hashCode;
xce.certificateId = certifcateId;
xce.validFrom = beginDate;
xce.validUntil = endDate;
xce.commit();
@ -132,7 +133,7 @@ public final class JCAUtil {
issuer,
keyType,
length,
hashCode,
certifcateId,
beginDate,
endDate);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2022, 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
@ -227,11 +227,13 @@ public final class PKIXCertPathValidator extends CertPathValidatorSpi {
X509ValidationEvent xve = new X509ValidationEvent();
if (xve.shouldCommit() || EventHelper.isLoggingSecurity()) {
int[] certIds = params.certificates().stream()
long[] certIds = params.certificates().stream()
.mapToInt(Certificate::hashCode)
.mapToLong(Integer::toUnsignedLong)
.toArray();
int anchorCertId = (anchorCert != null) ?
int hash = (anchorCert != null) ?
anchorCert.hashCode() : anchor.getCAPublicKey().hashCode();
long anchorCertId = Integer.toUnsignedLong(hash);
if (xve.shouldCommit()) {
xve.certificateId = anchorCertId;
int certificatePos = 1; // most trusted CA
@ -239,11 +241,10 @@ public final class PKIXCertPathValidator extends CertPathValidatorSpi {
xve.validationCounter = validationCounter.incrementAndGet();
xve.commit();
// now, iterate through remaining
for (int id : certIds) {
for (long id : certIds) {
xve.certificateId = id;
xve.certificatePosition = ++certificatePos;
xve.commit();
}
}
if (EventHelper.isLoggingSecurity()) {

View File

@ -1146,15 +1146,16 @@ final class Finished {
private static void recordEvent(SSLSessionImpl session) {
TLSHandshakeEvent event = new TLSHandshakeEvent();
if (event.shouldCommit() || EventHelper.isLoggingSecurity()) {
int peerCertificateId = 0;
int hash = 0;
try {
// use hash code for Id
peerCertificateId = session
hash = session
.getCertificateChain()[0]
.hashCode();
} catch (SSLPeerUnverifiedException e) {
// not verified msg
}
long peerCertificateId = Integer.toUnsignedLong(hash);
if (event.shouldCommit()) {
event.peerHost = session.getPeerHost();
event.peerPort = session.getPeerPort();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, 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
@ -29,6 +29,7 @@ import jdk.jfr.Category;
import jdk.jfr.Description;
import jdk.jfr.Label;
import jdk.jfr.Name;
import jdk.jfr.Unsigned;
import jdk.jfr.internal.MirrorEvent;
@Category({"Java Development Kit", "Security"})
@ -52,5 +53,6 @@ public final class TLSHandshakeEvent extends AbstractJDKEvent {
@Label("Certificate Id")
@Description("Peer Certificate Id")
@CertificateId
@Unsigned
public long certificateId;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, 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
@ -54,6 +54,7 @@ public final class X509CertificateEvent extends AbstractJDKEvent {
@Label("Certificate Id")
@CertificateId
@Unsigned
public long certificateId;
@Label("Valid From")

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, 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
@ -36,6 +36,7 @@ import jdk.jfr.internal.MirrorEvent;
public final class X509ValidationEvent extends AbstractJDKEvent {
@CertificateId
@Label("Certificate Id")
@Unsigned
public long certificateId;
@Label("Certificate Position")

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, 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
@ -28,6 +28,7 @@ package jdk.jfr.internal.tool;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
@ -38,6 +39,7 @@ import java.util.function.Predicate;
import jdk.jfr.EventType;
import jdk.jfr.Timespan;
import jdk.jfr.Timestamp;
import jdk.jfr.Unsigned;
import jdk.jfr.ValueDescriptor;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordedObject;
@ -47,7 +49,7 @@ import jdk.jfr.internal.consumer.JdkJfrConsumer;
abstract class EventPrintWriter extends StructuredWriter {
enum ValueType {
TIMESPAN, TIMESTAMP, OTHER
TIMESPAN, TIMESTAMP, UNSIGNED, OTHER
}
protected static final String STACK_TRACE_FIELD = "stackTrace";
@ -118,16 +120,31 @@ abstract class EventPrintWriter extends StructuredWriter {
valueType = determineValueType(v);
typeOfValues.put(v, valueType);
}
switch (valueType) {
case TIMESPAN:
return object.getDuration(v.getName());
case TIMESTAMP:
return PRIVATE_ACCESS.getOffsetDataTime(object, v.getName());
default:
return object.getValue(v.getName());
}
String name = v.getName();
return switch (valueType) {
case TIMESPAN -> object.getDuration(name);
case TIMESTAMP -> PRIVATE_ACCESS.getOffsetDataTime(object, name);
case UNSIGNED -> getUnsigned(object, name);
case OTHER -> object.getValue(name);
};
}
// It's expensive t check
private Object getUnsigned(RecordedObject object, String name) {
// RecordedObject::getLong handles unsigned byte, short, int
long value = object.getLong(name);
// If unsigned long value exceeds 2^63, return (upper << 32) + lower
if (value < 0) {
int upper = (int) (value >>> 32);
int lower = (int) value;
BigInteger u = BigInteger.valueOf(Integer.toUnsignedLong(upper));
u = u.shiftLeft(32);
BigInteger l = BigInteger.valueOf(Integer.toUnsignedLong(lower));
return u.add(l);
}
return Long.valueOf(value);
}
// Somewhat expensive operation
private ValueType determineValueType(ValueDescriptor v) {
if (v.getAnnotation(Timespan.class) != null) {
return ValueType.TIMESPAN;
@ -135,6 +152,12 @@ abstract class EventPrintWriter extends StructuredWriter {
if (v.getAnnotation(Timestamp.class) != null) {
return ValueType.TIMESTAMP;
}
if (v.getAnnotation(Unsigned.class) != null) {
return switch(v.getTypeName()) {
case "byte", "short", "int", "long" -> ValueType.UNSIGNED;
default -> ValueType.OTHER;
};
}
return ValueType.OTHER;
}
}

View File

@ -61,7 +61,7 @@ public class TestTLSHandshakeEvent {
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.HASHCODE);
Events.assertField(e, "certificateId").equal(TestTLSHandshake.CERT_ID);
Events.assertField(e, "cipherSuite").equal(TestTLSHandshake.CIPHER_SUITE);
return;
}

View File

@ -128,8 +128,9 @@ public class TestX509ValidationEvent {
switch (pos) {
// use public key of cert provided in TrustAnchor
case 1:
Asserts.assertEquals(e.getLong("certificateId"),
Long.valueOf(TestCertificate.ROOT_CA.certificate().getPublicKey().hashCode()));
int hash = TestCertificate.ROOT_CA.certificate().getPublicKey().hashCode();
Long id = Integer.toUnsignedLong(hash);
Asserts.assertEquals(e.getLong("certificateId"), id);
break;
case 2:
Events.assertField(e, "certificateId")

View File

@ -52,6 +52,7 @@ import org.xml.sax.helpers.DefaultHandler;
import jdk.jfr.Timespan;
import jdk.jfr.Timestamp;
import jdk.jfr.Unsigned;
import jdk.jfr.ValueDescriptor;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordedObject;
@ -149,6 +150,9 @@ public class TestPrintXML {
if (v.getAnnotation(Timespan.class) != null) {
expectedValue = re.getDuration(name);
}
if (expectedValue instanceof Number && v.getAnnotation(Unsigned.class) != null) {
expectedValue = Long.toUnsignedString(re.getLong(name));
}
if (!compare(expectedValue, xmlValue)) {
return false;
}

View File

@ -40,12 +40,12 @@ public class TestTLSHandshakeLog {
l.addExpected("Subject:CN=Regression Test");
l.addExpected("Key type:EC, Length:256");
l.addExpected("FINE: ValidationChain: " +
TestTLSHandshake.ANCHOR_HASHCODE +
", " + TestTLSHandshake.HASHCODE);
TestTLSHandshake.ANCHOR_CERT_ID +
", " + TestTLSHandshake.CERT_ID);
l.addExpected("SunJSSE Test Serivce");
l.addExpected("TLSHandshake:");
l.addExpected("TLSv1.2");
l.addExpected(TestTLSHandshake.CIPHER_SUITE +", " + TestTLSHandshake.HASHCODE);
l.addExpected(TestTLSHandshake.CIPHER_SUITE +", " + TestTLSHandshake.CERT_ID);
l.testExpected();
}

View File

@ -22,6 +22,7 @@
*/
package jdk.test.lib.json;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@ -317,7 +318,7 @@ public interface JSONValue {
var value = builder.toString();
if (isInteger) {
Long.parseLong(value);
new BigInteger(value);
return new JSONString(value);
} else {
Double.parseDouble(value);

View File

@ -139,13 +139,13 @@ public enum TestCertificate {
public String encoded;
TestCertificate(String serialNumber, String subject, String issuer,
long certId, String encoded) {
int hash, String encoded) {
this.serialNumber = serialNumber;
this.subject = subject;
this.issuer = issuer;
this.algorithm = "SHA256withRSA";
this.encoded = encoded;
this.certId = certId;
this.certId = Integer.toUnsignedLong(hash);
this.keyType = "RSA";
this.keyLength = 2048;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, 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
@ -33,8 +33,8 @@ public final class TestTLSHandshake extends SSLSocketTest {
public static final String CIPHER_SUITE =
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
public static final long HASHCODE = -1057291798L;
public static final long ANCHOR_HASHCODE = 1688661792L;
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 = "edbec8f705af2514";
public static final String ANCHOR_CERT_SERIAL = "8e191778b2f331be";