8296229: JFR: jfr tool should print unsigned values correctly
Reviewed-by: coffeys, mgronlun
This commit is contained in:
parent
e7c2a8e60e
commit
87b809a2cb
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user