8148188: Enhance the security libraries to record events of interest

Reviewed-by: egahlin, mullan, weijun, xuelei
This commit is contained in:
Sean Coffey 2018-11-20 13:12:48 +00:00
parent dc260a5369
commit 73ad9c4a00
35 changed files with 2617 additions and 8 deletions

View File

@ -30,6 +30,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.io.*;
import java.net.URL;
import jdk.internal.event.EventHelper;
import jdk.internal.event.SecurityPropertyModificationEvent;
import jdk.internal.access.SharedSecrets;
import jdk.internal.util.StaticProperty;
import sun.security.util.Debug;
@ -792,9 +794,19 @@ public final class Security {
* @see java.security.SecurityPermission
*/
public static void setProperty(String key, String datum) {
check("setProperty."+key);
check("setProperty." + key);
props.put(key, datum);
invalidateSMCache(key); /* See below. */
SecurityPropertyModificationEvent spe = new SecurityPropertyModificationEvent();
// following is a no-op if event is disabled
spe.key = key;
spe.value = datum;
spe.commit();
if (EventHelper.isLoggingSecurity()) {
EventHelper.logSecurityPropertyEvent(key, datum);
}
}
/*

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.event;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* A helper class to have events logged to a JDK Event Logger.
*/
public final class EventHelper {
private static final System.Logger.Level LOG_LEVEL = System.Logger.Level.DEBUG;
// helper class used for logging security related events for now
private static final String SECURITY_LOGGER_NAME = "jdk.event.security";
private static final System.Logger SECURITY_LOGGER =
System.getLogger(SECURITY_LOGGER_NAME);
private static final boolean LOGGING_SECURITY =
SECURITY_LOGGER.isLoggable(LOG_LEVEL);
public static void logTLSHandshakeEvent(Instant start,
String peerHost,
int peerPort,
String cipherSuite,
String protocolVersion,
long peerCertId) {
String prepend = getDurationString(start);
SECURITY_LOGGER.log(LOG_LEVEL, prepend +
" TLSHandshake: {0}:{1,number,#}, {2}, {3}, {4,number,#}",
peerHost, peerPort, protocolVersion, cipherSuite, peerCertId);
}
public static void logSecurityPropertyEvent(String key,
String value) {
if (isLoggingSecurity()) {
SECURITY_LOGGER.log(LOG_LEVEL,
"SecurityPropertyModification: key:{0}, value:{1}", key, value);
}
}
public static void logX509ValidationEvent(int anchorCertId,
int[] certIds) {
String codes = IntStream.of(certIds)
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));
SECURITY_LOGGER.log(LOG_LEVEL,
"ValidationChain: {0,number,#}, {1}", anchorCertId, codes);
}
public static void logX509CertificateEvent(String algId,
String serialNum,
String subject,
String issuer,
String keyType,
int length,
long certId,
long beginDate,
long endDate) {
SECURITY_LOGGER.log(LOG_LEVEL, "X509Certificate: Alg:{0}, Serial:{1}" +
", Subject:{2}, Issuer:{3}, Key type:{4}, Length:{5,number,#}" +
", Cert Id:{6,number,#}, Valid from:{7}, Valid until:{8}",
algId, serialNum, subject, issuer, keyType, length,
certId, new Date(beginDate), new Date(endDate));
}
/**
* Method to calculate a duration timestamp for events which measure
* the start and end times of certain operations.
* @param start Instant indicating when event started recording
* @return A string representing duraction from start time to
* time of this method call. Empty string is start is null.
*/
private static String getDurationString(Instant start) {
if (start != null) {
Duration duration = Duration.between(start, Instant.now());
long micros = duration.toNanos() / 1_000;
if (micros < 1_000_000) {
return "duration = " + (micros / 1_000.0) + " ms:";
} else {
return "duration = " + ((micros / 1_000) / 1_000.0) + " s:";
}
} else {
return "";
}
}
/**
* Helper to determine if security events are being logged
* at a preconfigured logging level. The configuration value
* is read once at class initialization.
*
* @return boolean indicating whether an event should be logged
*/
public static boolean isLoggingSecurity() {
return LOGGING_SECURITY;
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.event;
/**
* Event details relating to the modification of a Security property.
*/
public final class SecurityPropertyModificationEvent extends Event {
public String key;
public String value;
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.event;
/**
* Event recording details of successful TLS handshakes.
*/
public final class TLSHandshakeEvent extends Event {
public String peerHost;
public int peerPort;
public String protocolVersion;
public String cipherSuite;
public long certificateId;
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.event;
/**
* Event recording details of X.509 Certificate.
*/
public final class X509CertificateEvent extends Event {
public String algorithm;
public String serialNumber;
public String subject;
public String issuer;
public String keyType;
public int keyLength;
public long certificateId;
public long validFrom;
public long validUntil;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.event;
/**
* Event recording details of X.509 Certificate serial numbers
* used in X509 cert path validation.
*/
public final class X509ValidationEvent extends Event {
public long certificateId;
public int certificatePosition;
public long validationCounter;
}

View File

@ -26,12 +26,15 @@
package sun.security.provider;
import java.io.*;
import java.security.PublicKey;
import java.util.*;
import java.security.cert.*;
import jdk.internal.event.EventHelper;
import jdk.internal.event.X509CertificateEvent;
import sun.security.util.KeyUtil;
import sun.security.util.Pem;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CRLImpl;
import sun.security.x509.*;
import sun.security.pkcs.PKCS7;
import sun.security.provider.certpath.X509CertPath;
import sun.security.provider.certpath.X509CertificatePair;
@ -101,6 +104,8 @@ public class X509Factory extends CertificateFactorySpi {
}
cert = new X509CertImpl(encoding);
addToCache(certCache, cert.getEncodedInternal(), cert);
// record cert details if necessary
commitEvent(cert);
return cert;
} else {
throw new IOException("Empty input");
@ -762,4 +767,43 @@ public class X509Factory extends CertificateFactorySpi {
}
return tag;
}
private void commitEvent(X509CertImpl info) {
X509CertificateEvent xce = new X509CertificateEvent();
if (xce.shouldCommit() || EventHelper.isLoggingSecurity()) {
PublicKey pKey = info.getPublicKey();
String algId = info.getSigAlgName();
String serNum = info.getSerialNumber().toString(16);
String subject = info.getSubjectDN().getName();
String issuer = info.getIssuerDN().getName();
String keyType = pKey.getAlgorithm();
int length = KeyUtil.getKeySize(pKey);
int hashCode = info.hashCode();
long beginDate = info.getNotBefore().getTime();
long endDate = info.getNotAfter().getTime();
if (xce.shouldCommit()) {
xce.algorithm = algId;
xce.serialNumber = serNum;
xce.subject = subject;
xce.issuer = issuer;
xce.keyType = keyType;
xce.keyLength = length;
xce.certificateId = hashCode;
xce.validFrom = beginDate;
xce.validUntil = endDate;
xce.commit();
}
if (EventHelper.isLoggingSecurity()) {
EventHelper.logX509CertificateEvent(algId,
serNum,
subject,
issuer,
keyType,
length,
hashCode,
beginDate,
endDate);
}
}
}
}

View File

@ -29,7 +29,10 @@ import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.cert.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import jdk.internal.event.X509ValidationEvent;
import jdk.internal.event.EventHelper;
import sun.security.provider.certpath.PKIX.ValidatorParams;
import sun.security.validator.Validator;
import sun.security.x509.X509CertImpl;
@ -47,6 +50,7 @@ import sun.security.util.Debug;
public final class PKIXCertPathValidator extends CertPathValidatorSpi {
private static final Debug debug = Debug.getInstance("certpath");
private static final AtomicLong validationCounter = new AtomicLong();
/**
* Default constructor.
@ -234,7 +238,33 @@ public final class PKIXCertPathValidator extends CertPathValidatorSpi {
params.certificates(),
certPathCheckers);
X509ValidationEvent xve = new X509ValidationEvent();
if (xve.shouldCommit() || EventHelper.isLoggingSecurity()) {
int[] certIds = params.certificates().stream()
.mapToInt(x -> x.hashCode())
.toArray();
int anchorCertId =
anchor.getTrustedCert().hashCode();
if (xve.shouldCommit()) {
xve.certificateId = anchorCertId;
int certificatePos = 1; //anchor cert
xve.certificatePosition = certificatePos;
xve.validationCounter = validationCounter.incrementAndGet();
xve.commit();
// now, iterate through remaining
for (int id : certIds) {
xve.certificateId = id;
xve.certificatePosition = ++certificatePos;
xve.commit();
}
}
if (EventHelper.isLoggingSecurity()) {
EventHelper.logX509ValidationEvent(anchorCertId, certIds);
}
}
return new PKIXCertPathValidatorResult(anchor, pc.getPolicyTree(),
bc.getPublicKey());
}
}

View File

@ -40,6 +40,10 @@ import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLPeerUnverifiedException;
import jdk.internal.event.EventHelper;
import jdk.internal.event.TLSHandshakeEvent;
import sun.security.internal.spec.TlsPrfParameterSpec;
import sun.security.ssl.CipherSuite.HashAlg;
import static sun.security.ssl.CipherSuite.HashAlg.H_NONE;
@ -548,6 +552,7 @@ final class Finished {
// handshake context cleanup.
chc.handshakeFinished = true;
recordEvent(chc.conContext.conSession);
// May need to retransmit the last flight for DTLS.
if (!chc.sslContext.isDTLS()) {
@ -597,6 +602,7 @@ final class Finished {
// handshake context cleanup.
shc.handshakeFinished = true;
recordEvent(shc.conContext.conSession);
// May need to retransmit the last flight for DTLS.
if (!shc.sslContext.isDTLS()) {
@ -730,6 +736,8 @@ final class Finished {
// handshake context cleanup.
chc.handshakeFinished = true;
chc.conContext.finishHandshake();
recordEvent(chc.conContext.conSession);
// The handshake message has been delivered.
return null;
@ -1063,6 +1071,7 @@ final class Finished {
if (!shc.sslContext.isDTLS()) {
shc.conContext.finishHandshake();
}
recordEvent(shc.conContext.conSession);
//
// produce
@ -1074,4 +1083,35 @@ final class Finished {
}
}
private static void recordEvent(SSLSessionImpl session) {
TLSHandshakeEvent event = new TLSHandshakeEvent();
if (event.shouldCommit() || EventHelper.isLoggingSecurity()) {
int peerCertificateId = 0;
try {
// use hash code for Id
peerCertificateId = session
.getCertificateChain()[0]
.hashCode();
} catch (SSLPeerUnverifiedException e) {
// not verified msg
}
if (event.shouldCommit()) {
event.peerHost = session.getPeerHost();
event.peerPort = session.getPeerPort();
event.cipherSuite = session.getCipherSuite();
event.protocolVersion = session.getProtocol();
event.certificateId = peerCertificateId;
event.commit();
}
if (EventHelper.isLoggingSecurity()) {
EventHelper.logTLSHandshakeEvent(null,
session.getPeerHost(),
session.getPeerPort(),
session.getCipherSuite(),
session.getProtocol(),
peerCertificateId);
}
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.events;
import jdk.jfr.Label;
import jdk.jfr.Relational;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Label("X509 Certificate Id")
@Relational
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CertificateId {
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.events;
import jdk.jfr.*;
import jdk.jfr.internal.MirrorEvent;
@Category({"Java Development Kit", "Security"})
@Label("Security Property Modification")
@Name("jdk.SecurityPropertyModification")
@Description("Modification of Security property")
@MirrorEvent(className = "jdk.internal.event.SecurityPropertyModificationEvent")
public final class SecurityPropertyModificationEvent extends AbstractJDKEvent {
@Label("Key")
public String key;
@Label("Value")
public String value;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.events;
import jdk.jfr.Category;
import jdk.jfr.Description;
import jdk.jfr.Label;
import jdk.jfr.Name;
import jdk.jfr.internal.MirrorEvent;
@Category({"Java Development Kit", "Security"})
@Label("TLS Handshake")
@Name("jdk.TLSHandshake")
@Description("Parameters used in TLS Handshake")
@MirrorEvent(className = "jdk.internal.event.TLSHandshakeEvent")
public final class TLSHandshakeEvent extends AbstractJDKEvent {
@Label("Peer Host")
public String peerHost;
@Label("Peer Port")
public int peerPort;
@Label("Protocol Version")
public String protocolVersion;
@Label("Cipher Suite")
public String cipherSuite;
@Label("Certificate Id")
@Description("Peer Certificate Id")
@CertificateId
public long certificateId;
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.events;
import jdk.jfr.*;
import jdk.jfr.internal.MirrorEvent;
@Category({"Java Development Kit", "Security"})
@Label("X509 Certificate")
@Name("jdk.X509Certificate")
@Description("Details of X.509 Certificate parsed by JDK")
@MirrorEvent(className = "jdk.internal.event.X509CertificateEvent")
public final class X509CertificateEvent extends AbstractJDKEvent {
@Label("Signature Algorithm")
public String algorithm;
@Label("Serial Number")
public String serialNumber;
@Label("Subject")
public String subject;
@Label("Issuer")
public String issuer;
@Label("Key Type")
public String keyType;
@Label("Key Length")
public int keyLength;
@Label("Certificate Id")
@CertificateId
public long certificateId;
@Label("Valid From")
@Timestamp(Timestamp.MILLISECONDS_SINCE_EPOCH)
public long validFrom;
@Label("Valid Until")
@Timestamp(Timestamp.MILLISECONDS_SINCE_EPOCH)
public long validUntil;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.events;
import jdk.jfr.*;
import jdk.jfr.internal.MirrorEvent;
@Category({"Java Development Kit", "Security"})
@Label("X509 Validation")
@Name("jdk.X509Validation")
@Description("Serial numbers from X.509 Certificates forming chain of trust")
@MirrorEvent(className = "jdk.internal.event.X509ValidationEvent")
public final class X509ValidationEvent extends AbstractJDKEvent {
@CertificateId
@Label("Certificate Id")
public long certificateId;
@Label("Certificate Position")
@Description("Certificate position in chain of trust, 1 = trust anchor")
public int certificatePosition;
@Label("Validation Counter")
public long validationCounter;
}

View File

@ -39,8 +39,12 @@ import jdk.jfr.events.ExceptionThrownEvent;
import jdk.jfr.events.FileForceEvent;
import jdk.jfr.events.FileReadEvent;
import jdk.jfr.events.FileWriteEvent;
import jdk.jfr.events.SecurityPropertyModificationEvent;
import jdk.jfr.events.SocketReadEvent;
import jdk.jfr.events.SocketWriteEvent;
import jdk.jfr.events.TLSHandshakeEvent;
import jdk.jfr.events.X509CertificateEvent;
import jdk.jfr.events.X509ValidationEvent;
import jdk.jfr.internal.JVM;
import jdk.jfr.internal.LogLevel;
import jdk.jfr.internal.LogTag;
@ -52,6 +56,10 @@ import jdk.jfr.internal.Utils;
public final class JDKEvents {
private static final Class<?>[] mirrorEventClasses = {
SecurityPropertyModificationEvent.class,
TLSHandshakeEvent.class,
X509CertificateEvent.class,
X509ValidationEvent.class
};
private static final Class<?>[] eventClasses = {
@ -64,7 +72,11 @@ public final class JDKEvents {
ExceptionStatisticsEvent.class,
ErrorThrownEvent.class,
ActiveSettingEvent.class,
ActiveRecordingEvent.class
ActiveRecordingEvent.class,
jdk.internal.event.SecurityPropertyModificationEvent.class,
jdk.internal.event.TLSHandshakeEvent.class,
jdk.internal.event.X509CertificateEvent.class,
jdk.internal.event.X509ValidationEvent.class
};
// This is a list of the classes with instrumentation code that should be applied.

View File

@ -593,6 +593,26 @@
<setting name="threshold" control="socket-io-threshold">20 ms</setting>
</event>
<event name="jdk.SecurityPropertyModification">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.TLSHandshake">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.X509Validation">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.X509Certificate">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.JavaExceptionThrow">
<setting name="enabled" control="enable-exceptions">false</setting>
<setting name="stackTrace">true</setting>

View File

@ -593,6 +593,26 @@
<setting name="threshold" control="socket-io-threshold">10 ms</setting>
</event>
<event name="jdk.SecurityPropertyModification">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.TLSHandshake">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.X509Validation">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.X509Certificate">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.JavaExceptionThrow">
<setting name="enabled" control="enable-exceptions">false</setting>
<setting name="stackTrace">true</setting>

View File

@ -173,6 +173,10 @@ public class TestDefaultConfigurations {
insertSetting(doc, EventNames.ActiveRecording, "threshold", "0 ns");
insertSetting(doc, EventNames.JavaExceptionThrow, "threshold", "0 ns");
insertSetting(doc, EventNames.JavaErrorThrow, "threshold", "0 ns");
insertSetting(doc, EventNames.SecurityProperty, "threshold", "0 ns");
insertSetting(doc, EventNames.TLSHandshake, "threshold", "0 ns");
insertSetting(doc, EventNames.X509Certificate, "threshold", "0 ns");
insertSetting(doc, EventNames.X509Validation, "threshold", "0 ns");
return doc;
}

View File

@ -201,6 +201,10 @@ public final class TestActiveSettingEvent {
settingValues.put(EventNames.ActiveRecording + "#threshold", "0 ns");
settingValues.put(EventNames.JavaExceptionThrow + "#threshold", "0 ns");
settingValues.put(EventNames.JavaErrorThrow + "#threshold", "0 ns");
settingValues.put(EventNames.SecurityProperty + "#threshold", "0 ns");
settingValues.put(EventNames.TLSHandshake + "#threshold", "0 ns");
settingValues.put(EventNames.X509Certificate + "#threshold", "0 ns");
settingValues.put(EventNames.X509Validation + "#threshold", "0 ns");
try (Recording recording = new Recording(c)) {
Map<Long, EventType> eventTypes = new HashMap<>();

View File

@ -64,8 +64,8 @@ public final class TestModuleEvents {
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
assertDependency(events, "jdk.jfr", "java.base"); // jdk.jfr requires java.base (by edfault)
assertDependency(events, "java.base", "jdk.jfr"); // java.base require jdk.jfr for JDK events, i.e. FileRead
assertDependency(events, "jdk.jfr", "java.base"); // jdk.jfr requires java.base (by default)
assertDependency(events, "java.base", "jdk.jfr"); // java.base requires jdk.jfr for JDK events, i.e. FileRead
recording.close();
}
@ -97,8 +97,9 @@ public final class TestModuleEvents {
events.stream().forEach((ev) -> {
String exportedPackage = getValue(ev.getValue("exportedPackage"), "name", UNNAMED);
String toModule = getValue(ev.getValue("targetModule"), "name", UNNAMED);
edges.put(exportedPackage, toModule);
if (!toModule.equals("jdk.proxy1")) { // ignore jdk.proxy1 module
edges.put(exportedPackage, toModule);
}
});
// We expect

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.event.security;
import java.security.Security;
import java.util.List;
import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent;
import jdk.test.lib.Asserts;
import jdk.test.lib.jfr.EventNames;
import jdk.test.lib.jfr.Events;
import jdk.test.lib.security.JDKSecurityProperties;
/*
* @test
* @bug 8148188
* @summary Enhance the security libraries to record events of interest
* @key jfr
* @library /test/lib
* @run main/othervm jdk.jfr.event.security.TestSecurityPropertyModificationEvent
*/
public class TestSecurityPropertyModificationEvent {
static List<String> keys = JDKSecurityProperties.getKeys();
static String keyValue = "shouldBecomeAnEvent";
public static void main(String[] args) throws Exception {
try (Recording recording = new Recording()) {
recording.enable(EventNames.SecurityProperty);
recording.start();
for (String key: keys) {
Security.setProperty(key, keyValue);
}
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
Asserts.assertEquals(events.size(), keys.size(),
"Incorrect number of events");
assertEvent(events);
}
}
private static void assertEvent(List<RecordedEvent> events) throws Exception {
int i = 1;
for (RecordedEvent e : events) {
if (keys.contains(e.getString("key"))) {
Events.assertField(e, "value").equal(keyValue);
i++;
} else {
System.out.println(events);
throw new Exception("Unexpected event at index:" + i);
}
}
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.event.security;
import java.util.List;
import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent;
import jdk.test.lib.jfr.EventNames;
import jdk.test.lib.jfr.Events;
import jdk.test.lib.security.TestTLSHandshake;
/*
* @test
* @bug 8148188
* @summary Enhance the security libraries to record events of interest
* @key jfr
* @library /test/lib
* @run main/othervm jdk.jfr.event.security.TestTLSHandshakeEvent
*/
public class TestTLSHandshakeEvent {
public static void main(String[] args) throws Exception {
try (Recording recording = new Recording()) {
recording.enable(EventNames.TLSHandshake);
recording.start();
TestTLSHandshake handshake = new TestTLSHandshake();
handshake.run();
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
Events.hasEvents(events);
assertEvent(events, handshake);
}
}
private static void assertEvent(List<RecordedEvent> events, TestTLSHandshake handshake) 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.HASHCODE);
Events.assertField(e, "cipherSuite").equal(TestTLSHandshake.CIPHER_SUITE);
return;
}
}
System.out.println(events);
throw new Exception("Could not find event with hostname: " + handshake.peerHost);
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.event.security;
import java.security.cert.CertificateFactory;
import java.util.List;
import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent;
import jdk.test.lib.Asserts;
import jdk.test.lib.jfr.EventNames;
import jdk.test.lib.jfr.Events;
import jdk.test.lib.security.TestCertificate;
/*
* @test
* @bug 8148188
* @summary Enhance the security libraries to record events of interest
* @key jfr
* @library /test/lib
* @run main/othervm jdk.jfr.event.security.TestX509CertificateEvent
*/
public class TestX509CertificateEvent {
public static void main(String[] args) throws Exception {
try (Recording recording = new Recording()) {
recording.enable(EventNames.X509Certificate);
recording.start();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
TestCertificate.ONE.generate(cf);
TestCertificate.TWO.generate(cf);
// Generate twice to make sure only one event per certificate is generated
TestCertificate.ONE.generate(cf);
TestCertificate.TWO.generate(cf);
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
Asserts.assertEquals(events.size(), 2, "Incorrect number of X509Certificate events");
assertEvent(events, TestCertificate.ONE);
assertEvent(events, TestCertificate.TWO);
}
}
private static void assertEvent(List<RecordedEvent> events, TestCertificate cert) throws Exception {
for (RecordedEvent e : events) {
if (e.getLong("certificateId") == cert.certId) {
Events.assertField(e, "algorithm").equal(cert.algorithm);
Events.assertField(e, "subject").equal(cert.subject);
Events.assertField(e, "issuer").equal(cert.issuer);
Events.assertField(e, "keyType").equal(cert.keyType);
Events.assertField(e, "keyLength").equal(cert.keyLength);
Events.assertField(e, "serialNumber").equal(cert.serialNumber);
return;
}
}
System.out.println(events);
throw new Exception("Could not find event with cert Id: " + cert.certId);
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jfr.event.security;
import java.util.List;
import jdk.jfr.AnnotationElement;
import jdk.jfr.EventType;
import jdk.jfr.FlightRecorder;
import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent;
import jdk.test.lib.Asserts;
import jdk.test.lib.jfr.Events;
import jdk.test.lib.jfr.EventNames;
import jdk.test.lib.security.TestCertificate;
/*
* @test
* @bug 8148188
* @summary Enhance the security libraries to record events of interest
* @key jfr
* @library /test/lib
* @modules jdk.jfr/jdk.jfr.events
* @run main/othervm jdk.jfr.event.security.TestX509ValidationEvent
*/
public class TestX509ValidationEvent {
public static void main(String[] args) throws Exception {
try (Recording recording = new Recording()) {
recording.enable(EventNames.X509Validation);
recording.start();
// intermeditate certificate test
TestCertificate.generateChain(false);
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
Asserts.assertEquals(events.size(), 3, "Incorrect number of events");
assertEvent1(events);
}
try (Recording recording = new Recording()) {
recording.enable(EventNames.X509Validation);
recording.start();
// self signed certificate test
TestCertificate.generateChain(true);
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
Asserts.assertEquals(events.size(), 2, "Incorrect number of events");
assertEvent2(events);
}
}
private static void assertEvent1(List<RecordedEvent> events) throws Exception {
for (RecordedEvent e : events) {
int pos = e.getInt("certificatePosition");
switch (pos) {
case 1:
Events.assertField(e, "certificateId")
.equal(TestCertificate.ROOT_CA.certId);
break;
case 2:
Events.assertField(e, "certificateId")
.equal(TestCertificate.TWO.certId);
break;
case 3:
Events.assertField(e, "certificateId")
.equal(TestCertificate.ONE.certId);
break;
default:
System.out.println(events);
throw new Exception("Unexpected position:" + pos);
}
}
}
/*
* Self signed certificate test
*/
private static void assertEvent2(List<RecordedEvent> events) throws Exception {
for (RecordedEvent e : events) {
int pos = e.getInt("certificatePosition");
switch (pos) {
case 1:
case 2:
Events.assertField(e, "certificateId")
.equal(TestCertificate.ROOT_CA.certId);
break;
default:
System.out.println(events);
throw new Exception("Unexpected position:" + pos);
}
}
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.security.logging;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
public final class LogJvm {
private final static String LOGGING_ENABLED= "LOGGING_ENABLED";
private final static String LOGGING_DISABLED= "LOGGING_DISABLED";
private final static boolean debug = false;
private final List<String> expectedLogMessages = new ArrayList<>();
private final Class<?> clazz;
private final boolean loggingEnabled;
public LogJvm(Class<?> clazz, String[] args) {
this.clazz = clazz;
this.loggingEnabled = Arrays.asList(args).contains(LOGGING_ENABLED);
ensureLogging(args);
}
private void ensureLogging(String[] args) {
for(String s : args) {
if (s.equals(LOGGING_ENABLED) || s.equals(LOGGING_DISABLED)) {
return;
}
}
throw new RuntimeException(LogJvm.class.getName() +
" requires command line parameter " + LOGGING_ENABLED +
" or " + LOGGING_DISABLED);
}
public void addExpected(String logMsg) {
expectedLogMessages.add(logMsg);
}
public void testExpected() throws Exception {
OutputAnalyzer out = launchJVM();
if (debug) {
System.out.println("STDOUT DEBUG:\n " + out.getStdout());
System.out.println("\nSTDERR DEBUG:\n " + out.getStderr());
}
if (loggingEnabled) {
testLoggingEnabled(out);
} else {
testLoggingDisabled(out);
}
}
public OutputAnalyzer launchJVM() throws Exception {
List<String> args = new ArrayList<>();
if (loggingEnabled) {
args.add("-Djava.util.logging.config.file=" +
Paths.get(System.getProperty("test.src", "."), "logging.properties"));
}
args.add("--add-exports");
args.add("java.base/jdk.internal.event=ALL-UNNAMED");
args.add(clazz.getName());
System.out.println(args);
OutputAnalyzer out = ProcessTools.executeTestJava(args.toArray(new String[0]));
out.shouldHaveExitValue(0);
return out;
}
private void testLoggingDisabled(OutputAnalyzer out) {
for (String expected : expectedLogMessages) {
out.shouldNotContain(expected);
}
}
private void testLoggingEnabled(OutputAnalyzer out) {
for (String expected : expectedLogMessages) {
out.shouldContain(expected);
}
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.security.logging;
import java.security.Security;
import java.util.List;
import jdk.test.lib.security.JDKSecurityProperties;
/*
* @test
* @bug 8148188
* @summary Enhance the security libraries to record events of interest
* @library /test/lib /test/jdk
* @run main/othervm jdk.security.logging.TestSecurityPropertyModificationLog LOGGING_ENABLED
* @run main/othervm jdk.security.logging.TestSecurityPropertyModificationLog LOGGING_DISABLED
*/
public class TestSecurityPropertyModificationLog {
static List<String> keys = JDKSecurityProperties.getKeys();
static String keyValue = "shouldBecomeAnEvent";
public static void main(String[] args) throws Exception {
LogJvm l = new LogJvm(SetSecurityProperty.class, args);
for (String s: keys) {
l.addExpected("FINE: SecurityPropertyModification: key:" +
s + ", value:" + keyValue);
}
l.testExpected();
}
public static class SetSecurityProperty {
public static void main(String[] args) {
for (String s: keys) {
Security.setProperty(s, keyValue);
}
}
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.security.logging;
import jdk.test.lib.security.TestTLSHandshake;
/*
* @test
* @bug 8148188
* @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 {
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);
l.addExpected("Subject:CN=Regression Test");
l.addExpected("Key type:EC, Length:256");
l.addExpected("FINE: ValidationChain: " +
TestTLSHandshake.ANCHOR_HASHCODE +
", " + TestTLSHandshake.HASHCODE);
l.addExpected("SunJSSE Test Serivce");
l.addExpected("TLSHandshake:");
l.addExpected("TLSv1.2");
l.addExpected(TestTLSHandshake.CIPHER_SUITE +", " + TestTLSHandshake.HASHCODE);
l.testExpected();
}
public static class TLSHandshake {
public static void main(String[] args) throws Exception {
TestTLSHandshake handshake = new TestTLSHandshake();
handshake.run();
}
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.security.logging;
import java.security.cert.CertificateFactory;
import jdk.test.lib.security.TestCertificate;
/*
* @test
* @bug 8148188
* @summary Enhance the security libraries to record events of interest
* @library /test/lib /test/jdk
* @run main/othervm jdk.security.logging.TestX509CertificateLog LOGGING_ENABLED
* @run main/othervm jdk.security.logging.TestX509CertificateLog LOGGING_DISABLED
*/
public class TestX509CertificateLog {
public static void main(String[] args) throws Exception {
LogJvm l = new LogJvm(GenerateX509Certicate.class, args);
l.addExpected(
"FINE: X509Certificate: Alg:" + TestCertificate.ONE.algorithm +
", Serial:" + TestCertificate.ONE.serialNumber +
", Subject:" + TestCertificate.ONE.subject +
", Issuer:" + TestCertificate.ONE.issuer +
", Key type:" + TestCertificate.ONE.keyType +
", Length:" + TestCertificate.ONE.keyLength +
", Cert Id:" + TestCertificate.ONE.certId);
l.addExpected(
"FINE: X509Certificate: Alg:" + TestCertificate.TWO.algorithm +
", Serial:" + TestCertificate.TWO.serialNumber +
", Subject:" + TestCertificate.TWO.subject +
", Issuer:" + TestCertificate.TWO.issuer +
", Key type:" + TestCertificate.TWO.keyType +
", Length:" + TestCertificate.TWO.keyLength +
", Cert Id:" + TestCertificate.TWO.certId);
l.testExpected();
}
public static class GenerateX509Certicate {
public static void main(String[] args) throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
TestCertificate.ONE.generate(cf);
TestCertificate.TWO.generate(cf);
}
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.security.logging;
import jdk.test.lib.security.TestCertificate;
/*
* @test
* @bug 8148188
* @summary Enhance the security libraries to record events of interest
* @library /test/lib /test/jdk
* @run main/othervm jdk.security.logging.TestX509ValidationLog LOGGING_ENABLED
* @run main/othervm jdk.security.logging.TestX509ValidationLog LOGGING_DISABLED
*/
public class TestX509ValidationLog {
public static void main(String[] args) throws Exception {
LogJvm l = new LogJvm(GenerateCertificateChain.class, args);
l.addExpected("FINE: ValidationChain: " +
TestCertificate.ROOT_CA.certId + ", " +
TestCertificate.TWO.certId + ", " +
TestCertificate.ONE.certId);
l.addExpected("FINE: ValidationChain: " +
TestCertificate.ROOT_CA.certId + ", " +
TestCertificate.ROOT_CA.certId);
l.testExpected();
}
public static class GenerateCertificateChain {
public static void main(String[] args) throws Exception {
TestCertificate.generateChain(false);
// self signed test
TestCertificate.generateChain(true);
}
}
}

View File

@ -0,0 +1,13 @@
############################################################
# Configuration file for log testing
#
############################################################
handlers= java.util.logging.ConsoleHandler
.level= FINE
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
jdk.event.security.level = FINE

View File

@ -169,6 +169,10 @@ public class EventNames {
public final static String JavaErrorThrow = PREFIX + "JavaErrorThrow";
public final static String ModuleRequire = PREFIX + "ModuleRequire";
public final static String ModuleExport = PREFIX + "ModuleExport";
public final static String TLSHandshake = PREFIX + "TLSHandshake";
public final static String X509Certificate = PREFIX + "X509Certificate";
public final static String X509Validation = PREFIX + "X509Validation";
public final static String SecurityProperty = PREFIX + "SecurityPropertyModification";
// Flight Recorder
public final static String DumpReason = PREFIX + "DumpReason";

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.test.lib.security;
import java.util.List;
import java.security.Security;
public final class JDKSecurityProperties {
public static final List<String> jdkProps = List.of(
"com.sun.CORBA.ORBIorTypeCheckRegistryFilter",
"crypto.policy",
"jceks.key.serialFilter",
"jdk.certpath.disabledAlgorithms",
"keystore.type",
"krb5.kdc.bad.policy",
"login.config",
"networkaddress.cache.ttl",
"ocsp.responderURL",
"package.access",
"policy.allowSystemProperty",
"securerandom.drbg.config",
"security.provider.1",
"ssl.KeyManagerFactory.algorithm",
"sun.rmi.registry.registryFilter"
);
public static List getKeys() {
return jdkProps;
}
}

View File

@ -0,0 +1,891 @@
/*
* Copyright (c) 2016, 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.test.lib.security;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.KeyFactory;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Template to help speed up your client/server tests.
*
* Two examples that use this template:
* test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java
* test/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java
*/
public abstract class SSLSocketTest {
/*
* Run the test case.
*/
public void run() throws Exception {
bootup();
}
/*
* Define the server side application of the test for the specified socket.
*/
protected abstract void runServerApplication(SSLSocket socket) throws Exception;
/*
* Define the client side application of the test for the specified socket.
* This method is used if the returned value of
* isCustomizedClientConnection() is false.
*
* @param socket may be null is no client socket is generated.
*
* @see #isCustomizedClientConnection()
*/
protected abstract void runClientApplication(SSLSocket socket) throws Exception;
/*
* Define the client side application of the test for the specified
* server port. This method is used if the returned value of
* isCustomizedClientConnection() is true.
*
* Note that the client need to connect to the server port by itself
* for the actual message exchange.
*
* @see #isCustomizedClientConnection()
*/
protected void runClientApplication(int serverPort) throws Exception {
// blank
}
/*
* Create an instance of SSLContext for client use.
*/
protected SSLContext createClientSSLContext() throws Exception {
return createSSLContext(trustedCertStrs,
endEntityCertStrs, endEntityPrivateKeys,
endEntityPrivateKeyAlgs,
endEntityPrivateKeyNames,
getClientContextParameters());
}
/*
* Create an instance of SSLContext for server use.
*/
protected SSLContext createServerSSLContext() throws Exception {
return createSSLContext(trustedCertStrs,
endEntityCertStrs, endEntityPrivateKeys,
endEntityPrivateKeyAlgs,
endEntityPrivateKeyNames,
getServerContextParameters());
}
/*
* The parameters used to configure SSLContext.
*/
protected static final class ContextParameters {
final String contextProtocol;
final String tmAlgorithm;
final String kmAlgorithm;
ContextParameters(String contextProtocol,
String tmAlgorithm, String kmAlgorithm) {
this.contextProtocol = contextProtocol;
this.tmAlgorithm = tmAlgorithm;
this.kmAlgorithm = kmAlgorithm;
}
}
/*
* Get the client side parameters of SSLContext.
*/
protected ContextParameters getClientContextParameters() {
return new ContextParameters("TLS", "PKIX", "NewSunX509");
}
/*
* Get the server side parameters of SSLContext.
*/
protected ContextParameters getServerContextParameters() {
return new ContextParameters("TLS", "PKIX", "NewSunX509");
}
/*
* Does the client side use customized connection other than
* explicit Socket.connect(), for example, URL.openConnection()?
*/
protected boolean isCustomizedClientConnection() {
return false;
}
/*
* Configure the server side socket.
*/
protected void configureServerSocket(SSLServerSocket socket) {
}
/*
* =============================================
* Define the client and server side operations.
*
* If the client or server is doing some kind of object creation
* that the other side depends on, and that thread prematurely
* exits, you may experience a hang. The test harness will
* terminate all hung threads after its timeout has expired,
* currently 3 minutes by default, but you might try to be
* smart about it....
*/
/*
* Is the server ready to serve?
*/
private final CountDownLatch serverCondition = new CountDownLatch(1);
/*
* Is the client ready to handshake?
*/
private final CountDownLatch clientCondition = new CountDownLatch(1);
/*
* What's the server port? Use any free port by default
*/
private volatile int serverPort = 0;
/*
* Define the server side of the test.
*/
private void doServerSide() throws Exception {
// kick start the server side service
SSLContext context = createServerSSLContext();
SSLServerSocketFactory sslssf = context.getServerSocketFactory();
SSLServerSocket sslServerSocket =
(SSLServerSocket)sslssf.createServerSocket(serverPort);
configureServerSocket(sslServerSocket);
serverPort = sslServerSocket.getLocalPort();
// Signal the client, the server is ready to accept connection.
serverCondition.countDown();
// Try to accept a connection in 30 seconds.
SSLSocket sslSocket;
try {
sslServerSocket.setSoTimeout(30000);
sslSocket = (SSLSocket)sslServerSocket.accept();
} catch (SocketTimeoutException ste) {
// Ignore the test case if no connection within 30 seconds.
System.out.println(
"No incoming client connection in 30 seconds. " +
"Ignore in server side.");
return;
} finally {
sslServerSocket.close();
}
// handle the connection
try {
// Is it the expected client connection?
//
// Naughty test cases or third party routines may try to
// connection to this server port unintentionally. In
// order to mitigate the impact of unexpected client
// connections and avoid intermittent failure, it should
// be checked that the accepted connection is really linked
// to the expected client.
boolean clientIsReady =
clientCondition.await(30L, TimeUnit.SECONDS);
if (clientIsReady) {
// Run the application in server side.
runServerApplication(sslSocket);
} else { // Otherwise, ignore
// We don't actually care about plain socket connections
// for TLS communication testing generally. Just ignore
// the test if the accepted connection is not linked to
// the expected client or the client connection timeout
// in 30 seconds.
System.out.println(
"The client is not the expected one or timeout. " +
"Ignore in server side.");
}
} finally {
sslSocket.close();
}
}
/*
* Define the client side of the test.
*/
private void doClientSide() throws Exception {
// Wait for server to get started.
//
// The server side takes care of the issue if the server cannot
// get started in 90 seconds. The client side would just ignore
// the test case if the serer is not ready.
boolean serverIsReady =
serverCondition.await(90L, TimeUnit.SECONDS);
if (!serverIsReady) {
System.out.println(
"The server is not ready yet in 90 seconds. " +
"Ignore in client side.");
return;
}
if (isCustomizedClientConnection()) {
// Signal the server, the client is ready to communicate.
clientCondition.countDown();
// Run the application in client side.
runClientApplication(serverPort);
return;
}
SSLContext context = createClientSSLContext();
SSLSocketFactory sslsf = context.getSocketFactory();
try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) {
try {
sslSocket.connect(
new InetSocketAddress("localhost", serverPort), 15000);
} catch (IOException ioe) {
// The server side may be impacted by naughty test cases or
// third party routines, and cannot accept connections.
//
// Just ignore the test if the connection cannot be
// established.
System.out.println(
"Cannot make a connection in 15 seconds. " +
"Ignore in client side.");
return;
}
// OK, here the client and server get connected.
// Signal the server, the client is ready to communicate.
clientCondition.countDown();
// There is still a chance in theory that the server thread may
// wait client-ready timeout and then quit. The chance should
// be really rare so we don't consider it until it becomes a
// real problem.
// Run the application in client side.
runClientApplication(sslSocket);
}
}
/*
* =============================================
* Stuffs to customize the SSLContext instances.
*/
/*
* =======================================
* Certificates and keys used in the test.
*/
// Trusted certificates.
private final static String[] trustedCertStrs = {
// SHA256withECDSA, curve prime256v1
// Validity
// Not Before: May 22 07:18:16 2018 GMT
// Not After : May 17 07:18:16 2038 GMT
// Subject Key Identifier:
// 60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86
"-----BEGIN CERTIFICATE-----\n" +
"MIIBvjCCAWOgAwIBAgIJAIvFG6GbTroCMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" +
"AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
"ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYTAlVT\n" +
"MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTBZ\n" +
"MBMGByqGSM49AgEGCCqGSM49AwEHA0IABBz1WeVb6gM2mh85z3QlvaB/l11b5h0v\n" +
"LIzmkC3DKlVukZT+ltH2Eq1oEkpXuf7QmbM0ibrUgtjsWH3mULfmcWmjUDBOMB0G\n" +
"A1UdDgQWBBRgz71z//oaMNKk7NNJcUbvGjWghjAfBgNVHSMEGDAWgBRgz71z//oa\n" +
"MNKk7NNJcUbvGjWghjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCG\n" +
"6wluh1r2/T6L31mZXRKf9JxeSf9pIzoLj+8xQeUChQIhAJ09wAi1kV8yePLh2FD9\n" +
"2YEHlSQUAbwwqCDEVB5KxaqP\n" +
"-----END CERTIFICATE-----",
// -----BEGIN PRIVATE KEY-----
// MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/HcHdoLJCdq3haVd
// XZTSKP00YzM3xX97l98vGL/RI1KhRANCAAQc9VnlW+oDNpofOc90Jb2gf5ddW+Yd
// LyyM5pAtwypVbpGU/pbR9hKtaBJKV7n+0JmzNIm61ILY7Fh95lC35nFp
// -----END PRIVATE KEY-----
// SHA256withRSA, 2048 bits
// Validity
// Not Before: May 22 07:18:16 2018 GMT
// Not After : May 17 07:18:16 2038 GMT
// Subject Key Identifier:
// 0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
"-----BEGIN CERTIFICATE-----\n" +
"MIIDSTCCAjGgAwIBAgIJAI4ZF3iy8zG+MA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
"BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
"aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYT\n" +
"AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
"ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALpMcY7aWieXDEM1/YJf\n" +
"JW27b4nRIFZyEYhEloyGsKTuQiiQjc8cqRZFNXe2vwziDB4IyTEl0Hjl5QF6ZaQE\n" +
"huPzzwvQm1pv64KrRXrmj3FisQK8B5OWLty9xp6xDqsaMRoyObLK+oIb20T5fSlE\n" +
"evmo1vYjnh8CX0Yzx5Gr5ye6YSEHQvYOWEws8ad17OlyToR2KMeC8w4qo6rs59pW\n" +
"g7Mxn9vo22ImDzrtAbTbXbCias3xlE0Bp0h5luyf+5U4UgksoL9B9r2oP4GrLNEV\n" +
"oJk57t8lwaR0upiv3CnS8LcJELpegZub5ggqLY8ZPYFQPjlK6IzLOm6rXPgZiZ3m\n" +
"RL0CAwEAAaNQME4wHQYDVR0OBBYEFA3dk8n+S701t+iZeJD721o92xVMMB8GA1Ud\n" +
"IwQYMBaAFA3dk8n+S701t+iZeJD721o92xVMMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n" +
"hvcNAQELBQADggEBAJTRC3rKUUhVH07/1+stUungSYgpM08dY4utJq0BDk36BbmO\n" +
"0AnLDMbkwFdHEoqF6hQIfpm7SQTmXk0Fss6Eejm8ynYr6+EXiRAsaXOGOBCzF918\n" +
"/RuKOzqABfgSU4UBKECLM5bMfQTL60qx+HdbdVIpnikHZOFfmjCDVxoHsGyXc1LW\n" +
"Jhkht8IGOgc4PMGvyzTtRFjz01kvrVQZ75aN2E0GQv6dCxaEY0i3ypSzjUWAKqDh\n" +
"3e2OLwUSvumcdaxyCdZAOUsN6pDBQ+8VRG7KxnlRlY1SMEk46QgQYLbPDe/+W/yH\n" +
"ca4PejicPeh+9xRAwoTpiE2gulfT7Lm+fVM7Ruc=\n" +
"-----END CERTIFICATE-----",
// -----BEGIN PRIVATE KEY-----
// MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6THGO2lonlwxD
// Nf2CXyVtu2+J0SBWchGIRJaMhrCk7kIokI3PHKkWRTV3tr8M4gweCMkxJdB45eUB
// emWkBIbj888L0Jtab+uCq0V65o9xYrECvAeTli7cvcaesQ6rGjEaMjmyyvqCG9tE
// +X0pRHr5qNb2I54fAl9GM8eRq+cnumEhB0L2DlhMLPGndezpck6EdijHgvMOKqOq
// 7OfaVoOzMZ/b6NtiJg867QG0212womrN8ZRNAadIeZbsn/uVOFIJLKC/Qfa9qD+B
// qyzRFaCZOe7fJcGkdLqYr9wp0vC3CRC6XoGbm+YIKi2PGT2BUD45SuiMyzpuq1z4
// GYmd5kS9AgMBAAECggEAFHSoU2MuWwJ+2jJnb5U66t2V1bAcuOE1g5zkWvG/G5z9
// rq6Qo5kmB8f5ovdx6tw3MGUOklLwnRXBG3RxDJ1iokz3AvkY1clMNsDPlDsUrQKF
// JSO4QUBQTPSZhnsyfR8XHSU+qJ8Y+ohMfzpVv95BEoCzebtXdVgxVegBlcEmVHo2
// kMmkRN+bYNsr8eb2r+b0EpyumS39ZgKYh09+cFb78y3T6IFMGcVJTP6nlGBFkmA/
// 25pYeCF2tSki08qtMJZQAvKfw0Kviibk7ZxRbJqmc7B1yfnOEHP6ftjuvKl2+RP/
// +5P5f8CfIP6gtA0LwSzAqQX/hfIKrGV5j0pCqrD0kQKBgQDeNR6Xi4sXVq79lihO
// a1bSeV7r8yoQrS8x951uO+ox+UIZ1MsAULadl7zB/P0er92p198I9M/0Jth3KBuS
// zj45mucvpiiGvmQlMKMEfNq4nN7WHOu55kufPswQB2mR4J3xmwI+4fM/nl1zc82h
// De8JSazRldJXNhfx0RGFPmgzbwKBgQDWoVXrXLbCAn41oVnWB8vwY9wjt92ztDqJ
// HMFA/SUohjePep9UDq6ooHyAf/Lz6oE5NgeVpPfTDkgvrCFVKnaWdwALbYoKXT2W
// 9FlyJox6eQzrtHAacj3HJooXWuXlphKSizntfxj3LtMR9BmrmRJOfK+SxNOVJzW2
// +MowT20EkwKBgHmpB8jdZBgxI7o//m2BI5Y1UZ1KE5vx1kc7VXzHXSBjYqeV9FeF
// 2ZZLP9POWh/1Fh4pzTmwIDODGT2UPhSQy0zq3O0fwkyT7WzXRknsuiwd53u/dejg
// iEL2NPAJvulZ2+AuiHo5Z99LK8tMeidV46xoJDDUIMgTG+UQHNGhK5gNAoGAZn/S
// Cn7SgMC0CWSvBHnguULXZO9wH1wZAFYNLL44OqwuaIUFBh2k578M9kkke7woTmwx
// HxQTjmWpr6qimIuY6q6WBN8hJ2Xz/d1fwhYKzIp20zHuv5KDUlJjbFfqpsuy3u1C
// kts5zwI7pr1ObRbDGVyOdKcu7HI3QtR5qqyjwaUCgYABo7Wq6oHva/9V34+G3Goh
// 63bYGUnRw2l5BD11yhQv8XzGGZFqZVincD8gltNThB0Dc/BI+qu3ky4YdgdZJZ7K
// z51GQGtaHEbrHS5caV79yQ8QGY5mUVH3E+VXSxuIqb6pZq2DH4sTAEFHyncddmOH
// zoXBInYwRG9KE/Bw5elhUw==
// -----END PRIVATE KEY-----
// SHA256withDSA, 2048 bits
// Validity
// Not Before: May 22 07:18:18 2018 GMT
// Not After : May 17 07:18:18 2038 GMT
// Subject Key Identifier:
// 76:66:9E:F7:3B:DD:45:E5:3B:D9:72:3C:3F:F0:54:39:86:31:26:53
"-----BEGIN CERTIFICATE-----\n" +
"MIIErjCCBFSgAwIBAgIJAOktYLNCbr02MAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
"EwJVUzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2\n" +
"Y2UwHhcNMTgwNTIyMDcxODE4WhcNMzgwNTE3MDcxODE4WjA7MQswCQYDVQQGEwJV\n" +
"UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Uw\n" +
"ggNHMIICOQYHKoZIzjgEATCCAiwCggEBAO5GyPhSm0ze3LSu+gicdULLj05iOfTL\n" +
"UvZQ29sYz41zmqrLBQbdKiHqgJu2Re9sgTb5suLNjF047TOLPnU3jhPtWm2X8Xzi\n" +
"VGIcHym/Q/MeZxStt/88seqroI3WOKzIML2GcrishT+lcGrtH36Tf1+ue2Snn3PS\n" +
"WyxygNqPjllP5uUjYmFLvAf4QLMldkd/D2VxcwsHjB8y5iUZsXezc/LEhRZS/02m\n" +
"ivqlRw3AMkq/OVe/ZtxFWsP0nsfxEGdZuaUFpppGfixxFvymrB3+J51cTt+pZBDq\n" +
"D2y0DYfc+88iCs4jwHTfcDIpLb538HBjBj2rEgtQESQmB0ooD/+wsPsCIQC1bYch\n" +
"gElNtDYL3FgpLgNSUYp7gIWv9ehaC7LO2z7biQKCAQBitvFOnDkUja8NAF7lDpOV\n" +
"b5ipQ8SicBLW3kQamxhyuyxgZyy/PojZ/oPorkqW/T/A0rhnG6MssEpAtdiwVB+c\n" +
"rBYGo3bcwmExJhdOJ6dYuKFppPWhCwKMHs9npK+lqBMl8l5j58xlcFeC7ZfGf8GY\n" +
"GkhFW0c44vEQhMMbac6ZTTP4mw+1t7xJfmDMlLEyIpTXaAAk8uoVLWzQWnR40sHi\n" +
"ybvS0u3JxQkb7/y8tOOZu8qlz/YOS7lQ6UxUGX27Ce1E0+agfPphetoRAlS1cezq\n" +
"Wa7r64Ga0nkj1kwkcRqjgTiJx0NwnUXr78VAXFhVF95+O3lfqhvdtEGtkhDGPg7N\n" +
"A4IBBgACggEBAMmSHQK0w2i+iqUjOPzn0yNEZrzepLlLeQ1tqtn0xnlv5vBAeefD\n" +
"Pm9dd3tZOjufVWP7hhEz8xPobb1CS4e3vuQiv5UBfhdPL3f3l9T7JMAKPH6C9Vve\n" +
"OQXE5eGqbjsySbcmseHoYUt1WCSnSda1opX8zchX04e7DhGfE2/L9flpYEoSt8lI\n" +
"vMNjgOwvKdW3yvPt1/eBBHYNFG5gWPv/Q5KoyCtHS03uqGm4rNc/wZTIEEfd66C+\n" +
"QRaUltjOaHmtwOdDHaNqwhYZSVOip+Mo+TfyzHFREcdHLapo7ZXqbdYkRGxRR3d+\n" +
"3DfHaraJO0OKoYlPkr3JMvM/MSGR9AnZOcejUDBOMB0GA1UdDgQWBBR2Zp73O91F\n" +
"5TvZcjw/8FQ5hjEmUzAfBgNVHSMEGDAWgBR2Zp73O91F5TvZcjw/8FQ5hjEmUzAM\n" +
"BgNVHRMEBTADAQH/MAsGCWCGSAFlAwQDAgNHADBEAiBzriYE41M2y9Hy5ppkL0Qn\n" +
"dIlNc8JhXT/PHW7GDtViagIgMko8Qoj9gDGPK3+O9E8DC3wGiiF9CObM4LN387ok\n" +
"J+g=\n" +
"-----END CERTIFICATE-----"
// -----BEGIN PRIVATE KEY-----
// MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQDuRsj4UptM3ty0rvoInHVCy49O
// Yjn0y1L2UNvbGM+Nc5qqywUG3Soh6oCbtkXvbIE2+bLizYxdOO0ziz51N44T7Vpt
// l/F84lRiHB8pv0PzHmcUrbf/PLHqq6CN1jisyDC9hnK4rIU/pXBq7R9+k39frntk
// p59z0lsscoDaj45ZT+blI2JhS7wH+ECzJXZHfw9lcXMLB4wfMuYlGbF3s3PyxIUW
// Uv9Npor6pUcNwDJKvzlXv2bcRVrD9J7H8RBnWbmlBaaaRn4scRb8pqwd/iedXE7f
// qWQQ6g9stA2H3PvPIgrOI8B033AyKS2+d/BwYwY9qxILUBEkJgdKKA//sLD7AiEA
// tW2HIYBJTbQ2C9xYKS4DUlGKe4CFr/XoWguyzts+24kCggEAYrbxTpw5FI2vDQBe
// 5Q6TlW+YqUPEonAS1t5EGpsYcrssYGcsvz6I2f6D6K5Klv0/wNK4ZxujLLBKQLXY
// sFQfnKwWBqN23MJhMSYXTienWLihaaT1oQsCjB7PZ6SvpagTJfJeY+fMZXBXgu2X
// xn/BmBpIRVtHOOLxEITDG2nOmU0z+JsPtbe8SX5gzJSxMiKU12gAJPLqFS1s0Fp0
// eNLB4sm70tLtycUJG+/8vLTjmbvKpc/2Dku5UOlMVBl9uwntRNPmoHz6YXraEQJU
// tXHs6lmu6+uBmtJ5I9ZMJHEao4E4icdDcJ1F6+/FQFxYVRfefjt5X6ob3bRBrZIQ
// xj4OzQQjAiEAsceWOM8do4etxp2zgnoNXV8PUUyqWhz1+0srcKV7FR4=
// -----END PRIVATE KEY-----
};
// End entity certificate.
private final static String[] endEntityCertStrs = {
// SHA256withECDSA, curve prime256v1
// Validity
// Not Before: May 22 07:18:16 2018 GMT
// Not After : May 17 07:18:16 2038 GMT
// Authority Key Identifier:
// 60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86
"-----BEGIN CERTIFICATE-----\n" +
"MIIBqjCCAVCgAwIBAgIJAPLY8qZjgNRAMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" +
"AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
"ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYTAlVT\n" +
"MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTEY\n" +
"MBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n" +
"QgAEb+9n05qfXnfHUb0xtQJNS4JeSi6IjOfW5NqchvKnfJey9VkJzR7QHLuOESdf\n" +
"xlR7q8YIWgih3iWLGfB+wxHiOqMjMCEwHwYDVR0jBBgwFoAUYM+9c//6GjDSpOzT\n" +
"SXFG7xo1oIYwCgYIKoZIzj0EAwIDSAAwRQIgWpRegWXMheiD3qFdd8kMdrkLxRbq\n" +
"1zj8nQMEwFTUjjQCIQDRIrAjZX+YXHN9b0SoWWLPUq0HmiFIi8RwMnO//wJIGQ==\n" +
"-----END CERTIFICATE-----",
// SHA256withRSA, 2048 bits
// Validity
// Not Before: May 22 07:18:16 2018 GMT
// Not After : May 17 07:18:16 2038 GMT
// Authority Key Identifier:
// 0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
"-----BEGIN CERTIFICATE-----\n" +
"MIIDNjCCAh6gAwIBAgIJAO2+yPcFryUTMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
"BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
"aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYT\n" +
"AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
"ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC\n" +
"AQ8AMIIBCgKCAQEAszfBobWfZIp8AgC6PiWDDavP65mSvgCXUGxACbxVNAfkLhNR\n" +
"QOsHriRB3X1Q3nvO9PetC6wKlvE9jlnDDj7D+1j1r1CHO7ms1fq8rfcQYdkanDtu\n" +
"4AlHo8v+SSWX16MIXFRYDj2VVHmyPtgbltcg4zGAuwT746FdLI94uXjJjq1IOr/v\n" +
"0VIlwE5ORWH5Xc+5Tj+oFWK0E4a4GHDgtKKhn2m72hN56/GkPKGkguP5NRS1qYYV\n" +
"/EFkdyQMOV8J1M7HaicSft4OL6eKjTrgo93+kHk+tv0Dc6cpVBnalX3TorG8QI6B\n" +
"cHj1XQd78oAlAC+/jF4pc0mwi0un49kdK9gRfQIDAQABoyMwITAfBgNVHSMEGDAW\n" +
"gBQN3ZPJ/ku9NbfomXiQ+9taPdsVTDANBgkqhkiG9w0BAQsFAAOCAQEApXS0nKwm\n" +
"Kp8gpmO2yG1rpd1+2wBABiMU4JZaTqmma24DQ3RzyS+V2TeRb29dl5oTUEm98uc0\n" +
"GPZvhK8z5RFr4YE17dc04nI/VaNDCw4y1NALXGs+AHkjoPjLyGbWpi1S+gfq2sNB\n" +
"Ekkjp6COb/cb9yiFXOGVls7UOIjnVZVd0r7KaPFjZhYh82/f4PA/A1SnIKd1+nfH\n" +
"2yk7mSJNC7Z3qIVDL8MM/jBVwiC3uNe5GPB2uwhd7k5LGAVN3j4HQQGB0Sz+VC1h\n" +
"92oi6xDa+YBva2fvHuCd8P50DDjxmp9CemC7rnZ5j8egj88w14X44Xjb/Fd/ApG9\n" +
"e57NnbT7KM+Grw==\n" +
"-----END CERTIFICATE-----",
// SHA256withRSA, curv prime256v1
// Validity
// Not Before: May 22 07:18:16 2018 GMT
// Not After : May 21 07:18:16 2028 GMT
// Authority Key Identifier:
// 0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
"-----BEGIN CERTIFICATE-----\n" +
"MIICazCCAVOgAwIBAgIJAO2+yPcFryUUMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
"BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
"aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0yODA1MjEwNzE4MTZaMFUxCzAJBgNVBAYT\n" +
"AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
"ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" +
"AQcDQgAE59MERNTlVZ1eeps8Z3Oue5ZkgQdPtD+WIE6tj3PbIKpxGPDxvfNP959A\n" +
"yQjEK/ehWQVrCMmNoEkIzY+IIBgB06MjMCEwHwYDVR0jBBgwFoAUDd2Tyf5LvTW3\n" +
"6Jl4kPvbWj3bFUwwDQYJKoZIhvcNAQELBQADggEBAFOTVEqs70ykhZiIdrEsF1Ra\n" +
"I3B2rLvwXZk52uSltk2/bzVvewA577ZCoxQ1pL7ynkisPfBN1uVYtHjM1VA3RC+4\n" +
"+TAK78dnI7otYjWoHp5rvs4l6c/IbOspS290IlNuDUxMErEm5wxIwj+Aukx/1y68\n" +
"hOyCvHBLMY2c1LskH1MMBbDuS1aI+lnGpToi+MoYObxGcV458vxuT8+wwV8Fkpvd\n" +
"ll8IIFmeNPRv+1E+lXbES6CSNCVaZ/lFhPgdgYKleN7sfspiz50DG4dqafuEAaX5\n" +
"xaK1NWXJxTRz0ROH/IUziyuDW6jphrlgit4+3NCzp6vP9hAJQ8Vhcj0n15BKHIQ=\n" +
"-----END CERTIFICATE-----",
// SHA256withDSA, 2048 bits
// Validity
// Not Before: May 22 07:18:20 2018 GMT
// Not After : May 17 07:18:20 2038 GMT
// Authority Key Identifier:
// 76:66:9E:F7:3B:DD:45:E5:3B:D9:72:3C:3F:F0:54:39:86:31:26:53
"-----BEGIN CERTIFICATE-----\n" +
"MIIEnDCCBEGgAwIBAgIJAP/jh1qVhNVjMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
"EwJVUzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2\n" +
"Y2UwHhcNMTgwNTIyMDcxODIwWhcNMzgwNTE3MDcxODIwWjBVMQswCQYDVQQGEwJV\n" +
"UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
"GDAWBgNVBAMMD1JlZ3Jlc3Npb24gVGVzdDCCA0cwggI6BgcqhkjOOAQBMIICLQKC\n" +
"AQEAmlavgoJrMcjqWRVcDE2dmWAPREgnzQvneEDef68cprDzjSwvOs5QeFyx75ib\n" +
"ado1e6jO/rW1prCGWHDD1oA/Tn4Pk3vu0nUxzvl1qATc+aJbpUU5Op0bvp6LbCsQ\n" +
"QslV9FeRh7Eb7bP6gpc/kHCBzEgC1VCK7prccXWy+t6SMOHbND3h+UbckfSaUuaV\n" +
"sVJNTD1D6GElfRj4Nmz1BGPfSYvKorwNZEU3gXwFgtDoAcGx7tcyClLpDHfqRfw/\n" +
"7yiqLyeiP7D4hl5lMNouJWDlAdMFp0FMgS3s9VDFinIcr6VtBWMTG7+4+czHAB+3\n" +
"fvrwlqNzhBn3uFHrekN/w8fNxwIhAJo7Sae1za7IMW0Q6hE5B4b+s2B/FaKPoA4E\n" +
"jtZu13B9AoIBAQCOZqLMKfvqZWUgT0PQ3QjR7dAFdd06I9Y3+TOQzZk1+j+vw/6E\n" +
"X4vFItX4gihb/u5Q9CdmpwhVGi7bvo+7+/IKeTgoQ6f5+PSug7SrWWUQ5sPwaZui\n" +
"zXZJ5nTeZDucFc2yFx0wgnjbPwiUxZklOT7xGiOMtzOTa2koCz5KuIBL+/wPKKxm\n" +
"ypo9VoY9xfbdU6LMXZv/lpD5XTM9rYHr/vUTNkukvV6Hpm0YMEWhVZKUJiqCqTqG\n" +
"XHaleOxSw6uQWB/+TznifcC7gB48UOQjCqOKf5VuwQneJLhlhU/jhRV3xtr+hLZa\n" +
"hW1wYhVi8cjLDrZFKlgEQqhB4crnJU0mJY+tA4IBBQACggEAID0ezl00/X8mv7eb\n" +
"bzovum1+DEEP7FM57k6HZEG2N3ve4CW+0m9Cd+cWPz8wkZ+M0j/Eqa6F0IdbkXEc\n" +
"Q7CuzvUyJ57xQ3L/WCgXsiS+Bh8O4Mz7GwW22CGmHqafbVv+hKBfr8MkskO6GJUt\n" +
"SUF/CVLzB4gMIvZMH26tBP2xK+i7FeEK9kT+nGdzQSZBAhFYpEVCBplHZO24/OYq\n" +
"1DNoU327nUuXIhmsfA8N0PjiWbIZIjTPwBGr9H0LpATI7DIDNcvRRvtROP+pBU9y\n" +
"fuykPkptg9C0rCM9t06bukpOSaEz/2VIQdLE8fHYFA6pHZ6CIc2+5cfvMgTPhcjz\n" +
"W2jCt6MjMCEwHwYDVR0jBBgwFoAUdmae9zvdReU72XI8P/BUOYYxJlMwCwYJYIZI\n" +
"AWUDBAMCA0gAMEUCIQCeI5fN08b9BpOaHdc3zQNGjp24FOL/RxlBLeBAorswJgIg\n" +
"JEZ8DhYxQy1O7mmZ2UIT7op6epWMB4dENjs0qWPmcKo=\n" +
"-----END CERTIFICATE-----"
};
// Private key in the format of PKCS#8.
private final static String[] endEntityPrivateKeys = {
//
// EC private key related to cert endEntityCertStrs[0].
//
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgn5K03bpTLjEtFQRa\n" +
"JUtx22gtmGEvvSUSQdimhGthdtihRANCAARv72fTmp9ed8dRvTG1Ak1Lgl5KLoiM\n" +
"59bk2pyG8qd8l7L1WQnNHtAcu44RJ1/GVHurxghaCKHeJYsZ8H7DEeI6",
//
// RSA private key related to cert endEntityCertStrs[1].
//
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzN8GhtZ9kinwC\n" +
"ALo+JYMNq8/rmZK+AJdQbEAJvFU0B+QuE1FA6weuJEHdfVDee870960LrAqW8T2O\n" +
"WcMOPsP7WPWvUIc7uazV+ryt9xBh2RqcO27gCUejy/5JJZfXowhcVFgOPZVUebI+\n" +
"2BuW1yDjMYC7BPvjoV0sj3i5eMmOrUg6v+/RUiXATk5FYfldz7lOP6gVYrQThrgY\n" +
"cOC0oqGfabvaE3nr8aQ8oaSC4/k1FLWphhX8QWR3JAw5XwnUzsdqJxJ+3g4vp4qN\n" +
"OuCj3f6QeT62/QNzpylUGdqVfdOisbxAjoFwePVdB3vygCUAL7+MXilzSbCLS6fj\n" +
"2R0r2BF9AgMBAAECggEASIkPkMCuw4WdTT44IwERus3IOIYOs2IP3BgEDyyvm4B6\n" +
"JP/iihDWKfA4zEl1Gqcni1RXMHswSglXra682J4kui02Ov+vzEeJIY37Ibn2YnP5\n" +
"ZjRT2s9GtI/S2o4hl8A/mQb2IMViFC+xKehTukhV4j5d6NPKk0XzLR7gcMjnYxwn\n" +
"l21fS6D2oM1xRG/di7sL+uLF8EXLRzfiWDNi12uQv4nwtxPKvuKhH6yzHt7YqMH0\n" +
"46pmDKDaxV4w1JdycjCb6NrCJOYZygoQobuZqOQ30UZoZsPJrtovkncFr1e+lNcO\n" +
"+aWDfOLCtTH046dEQh5oCShyXMybNlry/QHsOtHOwQKBgQDh2iIjs+FPpQy7Z3EX\n" +
"DGEvHYqPjrYO9an2KSRr1m9gzRlWYxKY46WmPKwjMerYtra0GP+TBHrgxsfO8tD2\n" +
"wUAII6sd1qup0a/Sutgf2JxVilLykd0+Ge4/Cs51tCdJ8EqDV2B6WhTewOY2EGvg\n" +
"JiKYkeNwgRX/9M9CFSAMAk0hUQKBgQDLJAartL3DoGUPjYtpJnfgGM23yAGl6G5r\n" +
"NSXDn80BiYIC1p0bG3N0xm3yAjqOtJAUj9jZbvDNbCe3GJfLARMr23legX4tRrgZ\n" +
"nEdKnAFKAKL01oM+A5/lHdkwaZI9yyv+hgSVdYzUjB8rDmzeVQzo1BT7vXypt2yV\n" +
"6O1OnUpCbQKBgA/0rzDChopv6KRcvHqaX0tK1P0rYeVQqb9ATNhpf9jg5Idb3HZ8\n" +
"rrk91BNwdVz2G5ZBpdynFl9G69rNAMJOCM4KZw5mmh4XOEq09Ivba8AHU7DbaTv3\n" +
"7QL7KnbaUWRB26HHzIMYVh0el6T+KADf8NXCiMTr+bfpfbL3dxoiF3zhAoGAbCJD\n" +
"Qse1dBs/cKYCHfkSOsI5T6kx52Tw0jS6Y4X/FOBjyqr/elyEexbdk8PH9Ar931Qr\n" +
"NKMvn8oA4iA/PRrXX7M2yi3YQrWwbkGYWYjtzrzEAdzmg+5eARKAeJrZ8/bg9l3U\n" +
"ttKaItJsDPlizn8rngy3FsJpR9aSAMK6/+wOiYkCgYEA1tZkI1rD1W9NYZtbI9BE\n" +
"qlJVFi2PBOJMKNuWdouPX3HLQ72GJSQff2BFzLTELjweVVJ0SvY4IipzpQOHQOBy\n" +
"5qh/p6izXJZh3IHtvwVBjHoEVplg1b2+I5e3jDCfqnwcQw82dW5SxOJMg1h/BD0I\n" +
"qAL3go42DYeYhu/WnECMeis=",
//
// EC private key related to cert endEntityCertStrs[2].
//
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGVc7hICpmp91jbYe\n" +
"nrr8nYHD37RZP3VENY+szuA7WjuhRANCAATn0wRE1OVVnV56mzxnc657lmSBB0+0\n" +
"P5YgTq2Pc9sgqnEY8PG980/3n0DJCMQr96FZBWsIyY2gSQjNj4ggGAHT",
//
// DSA private key related to cert endEntityCertStrs[3].
//
"MIICZQIBADCCAjoGByqGSM44BAEwggItAoIBAQCaVq+CgmsxyOpZFVwMTZ2ZYA9E\n" +
"SCfNC+d4QN5/rxymsPONLC86zlB4XLHvmJtp2jV7qM7+tbWmsIZYcMPWgD9Ofg+T\n" +
"e+7SdTHO+XWoBNz5olulRTk6nRu+notsKxBCyVX0V5GHsRvts/qClz+QcIHMSALV\n" +
"UIrumtxxdbL63pIw4ds0PeH5RtyR9JpS5pWxUk1MPUPoYSV9GPg2bPUEY99Ji8qi\n" +
"vA1kRTeBfAWC0OgBwbHu1zIKUukMd+pF/D/vKKovJ6I/sPiGXmUw2i4lYOUB0wWn\n" +
"QUyBLez1UMWKchyvpW0FYxMbv7j5zMcAH7d++vCWo3OEGfe4Uet6Q3/Dx83HAiEA\n" +
"mjtJp7XNrsgxbRDqETkHhv6zYH8Voo+gDgSO1m7XcH0CggEBAI5moswp++plZSBP\n" +
"Q9DdCNHt0AV13Toj1jf5M5DNmTX6P6/D/oRfi8Ui1fiCKFv+7lD0J2anCFUaLtu+\n" +
"j7v78gp5OChDp/n49K6DtKtZZRDmw/Bpm6LNdknmdN5kO5wVzbIXHTCCeNs/CJTF\n" +
"mSU5PvEaI4y3M5NraSgLPkq4gEv7/A8orGbKmj1Whj3F9t1Tosxdm/+WkPldMz2t\n" +
"gev+9RM2S6S9XoembRgwRaFVkpQmKoKpOoZcdqV47FLDq5BYH/5POeJ9wLuAHjxQ\n" +
"5CMKo4p/lW7BCd4kuGWFT+OFFXfG2v6EtlqFbXBiFWLxyMsOtkUqWARCqEHhyucl\n" +
"TSYlj60EIgIgLfA75+8KcKxdN8mr6gzGjQe7jPFGG42Ejhd7Q2F4wuw="
};
// Private key algorithm of endEntityPrivateKeys.
private final static String[] endEntityPrivateKeyAlgs = {
"EC",
"RSA",
"EC",
"DSA",
};
// Private key names of endEntityPrivateKeys.
private final static String[] endEntityPrivateKeyNames = {
"ecdsa",
"rsa",
"ec-rsa",
"dsa",
};
/*
* Create an instance of SSLContext with the specified trust/key materials.
*/
private SSLContext createSSLContext(
String[] trustedMaterials,
String[] keyMaterialCerts,
String[] keyMaterialKeys,
String[] keyMaterialKeyAlgs,
String[] keyMaterialKeyNames,
ContextParameters params) throws Exception {
KeyStore ts = null; // trust store
KeyStore ks = null; // key store
char passphrase[] = "passphrase".toCharArray();
// Generate certificate from cert string.
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// Import the trused certs.
ByteArrayInputStream is;
if (trustedMaterials != null && trustedMaterials.length != 0) {
ts = KeyStore.getInstance("JKS");
ts.load(null, null);
Certificate[] trustedCert =
new Certificate[trustedMaterials.length];
for (int i = 0; i < trustedMaterials.length; i++) {
String trustedCertStr = trustedMaterials[i];
is = new ByteArrayInputStream(trustedCertStr.getBytes());
try {
trustedCert[i] = cf.generateCertificate(is);
} finally {
is.close();
}
ts.setCertificateEntry("trusted-cert-" + i, trustedCert[i]);
}
}
// Import the key materials.
//
// Note that certification pathes bigger than one are not supported yet.
boolean hasKeyMaterials =
(keyMaterialCerts != null) && (keyMaterialCerts.length != 0) &&
(keyMaterialKeys != null) && (keyMaterialKeys.length != 0) &&
(keyMaterialKeyAlgs != null) && (keyMaterialKeyAlgs.length != 0) &&
(keyMaterialCerts.length == keyMaterialKeys.length) &&
(keyMaterialCerts.length == keyMaterialKeyAlgs.length);
if (hasKeyMaterials) {
ks = KeyStore.getInstance("JKS");
ks.load(null, null);
for (int i = 0; i < keyMaterialCerts.length; i++) {
String keyCertStr = keyMaterialCerts[i];
// generate the private key.
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
Base64.getMimeDecoder().decode(keyMaterialKeys[i]));
KeyFactory kf =
KeyFactory.getInstance(keyMaterialKeyAlgs[i]);
PrivateKey priKey = kf.generatePrivate(priKeySpec);
// generate certificate chain
is = new ByteArrayInputStream(keyCertStr.getBytes());
Certificate keyCert = null;
try {
keyCert = cf.generateCertificate(is);
} finally {
is.close();
}
Certificate[] chain = new Certificate[] { keyCert };
// import the key entry.
ks.setKeyEntry("cert-" + keyMaterialKeyNames[i],
priKey, passphrase, chain);
}
}
// Create an SSLContext object.
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(params.tmAlgorithm);
tmf.init(ts);
SSLContext context = SSLContext.getInstance(params.contextProtocol);
if (hasKeyMaterials && ks != null) {
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(params.kmAlgorithm);
kmf.init(ks, passphrase);
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} else {
context.init(null, tmf.getTrustManagers(), null);
}
return context;
}
/*
* =================================================
* Stuffs to boot up the client-server mode testing.
*/
private Thread clientThread = null;
private Thread serverThread = null;
private volatile Exception serverException = null;
private volatile Exception clientException = null;
/*
* Should we run the client or server in a separate thread?
* Both sides can throw exceptions, but do you have a preference
* as to which side should be the main thread.
*/
private static final boolean separateServerThread = false;
/*
* Boot up the testing, used to drive remainder of the test.
*/
private void bootup() throws Exception {
Exception startException = null;
try {
if (separateServerThread) {
startServer(true);
startClient(false);
} else {
startClient(true);
startServer(false);
}
} catch (Exception e) {
startException = e;
}
/*
* Wait for other side to close down.
*/
if (separateServerThread) {
if (serverThread != null) {
serverThread.join();
}
} else {
if (clientThread != null) {
clientThread.join();
}
}
/*
* When we get here, the test is pretty much over.
* Which side threw the error?
*/
Exception local;
Exception remote;
if (separateServerThread) {
remote = serverException;
local = clientException;
} else {
remote = clientException;
local = serverException;
}
Exception exception = null;
/*
* Check various exception conditions.
*/
if ((local != null) && (remote != null)) {
// If both failed, return the curthread's exception.
local.initCause(remote);
exception = local;
} else if (local != null) {
exception = local;
} else if (remote != null) {
exception = remote;
} else if (startException != null) {
exception = startException;
}
/*
* If there was an exception *AND* a startException,
* output it.
*/
if (exception != null) {
if (exception != startException && startException != null) {
exception.addSuppressed(startException);
}
throw exception;
}
// Fall-through: no exception to throw!
}
private void startServer(boolean newThread) throws Exception {
if (newThread) {
serverThread = new Thread() {
@Override
public void run() {
try {
doServerSide();
} catch (Exception e) {
/*
* Our server thread just died.
*
* Release the client, if not active already...
*/
logException("Server died", e);
serverException = e;
}
}
};
serverThread.start();
} else {
try {
doServerSide();
} catch (Exception e) {
logException("Server failed", e);
serverException = e;
}
}
}
private void startClient(boolean newThread) throws Exception {
if (newThread) {
clientThread = new Thread() {
@Override
public void run() {
try {
doClientSide();
} catch (Exception e) {
/*
* Our client thread just died.
*/
logException("Client died", e);
clientException = e;
}
}
};
clientThread.start();
} else {
try {
doClientSide();
} catch (Exception e) {
logException("Client failed", e);
clientException = e;
}
}
}
private synchronized void logException(String prefix, Throwable cause) {
System.out.println(prefix + ": " + cause);
cause.printStackTrace(System.out);
}
}

View File

@ -0,0 +1,175 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.test.lib.security;
import java.io.ByteArrayInputStream;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Date;
import java.util.List;
// Certificates taken from old ValWithAnchorByName testcase ***
public enum TestCertificate {
// Subject: CN=SSLCertificate, O=SomeCompany
// Issuer: CN=Intermediate CA Cert, O=SomeCompany
// Validity: Tue Aug 30 14:37:19 PDT 2016 to Wed Aug 30 14:37:19 PDT 2017
ONE("1000",
"CN=SSLCertificate, O=SomeCompany",
"CN=Intermediate CA Cert, O=SomeCompany",
-1063259762,
"-----BEGIN CERTIFICATE-----\n" +
"MIIDnTCCAoWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwNTEUMBIGA1UEChMLU29t\n" +
"ZUNvbXBhbnkxHTAbBgNVBAMTFEludGVybWVkaWF0ZSBDQSBDZXJ0MB4XDTE2MDgz\n" +
"MDIxMzcxOVoXDTE3MDgzMDIxMzcxOVowLzEUMBIGA1UEChMLU29tZUNvbXBhbnkx\n" +
"FzAVBgNVBAMTDlNTTENlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n" +
"MIIBCgKCAQEAjgv8KKE4CO0rbCjRLA1hXjRiSq30jeusCJ8frbRG+QOBgQ3j6jgc\n" +
"vk5wG1aTu7R4AFn0/HRDMzP9ZbRlZVIbJUTd8YiaNyZeyWapPnxHWrPCd5e1xopk\n" +
"ElieDdEH5FiLGtIrWy56CGA1hfQb1vUVYegyeY+TTtMFVHt0PrmMk4ZRgj/GtVNp\n" +
"BQQYIzaYAcrcWMeCn30ZrhaGAL1hsdgmEVV1wsTD4JeNMSwLwMYem7fg8ondGZIR\n" +
"kZuGtuSdOHu4Xz+mgDNXTeX/Bp/dQFucxCG+FOOM9Hoz72RY2W8YqgL38RlnwYWp\n" +
"nUNxhXWFH6vyINRQVEu3IgahR6HXjxM7LwIDAQABo4G8MIG5MBQGA1UdEQQNMAuC\n" +
"CWxvY2FsaG9zdDAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9s\n" +
"b2NhbGhvc3Q6NDIzMzMwHwYDVR0jBBgwFoAUYT525lwHCI4CmuWs8a7poaeKRJ4w\n" +
"HQYDVR0OBBYEFCaQnOX4L1ovqyfeKuoay+kI+lXgMA4GA1UdDwEB/wQEAwIFoDAd\n" +
"BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEB\n" +
"AD8dqQIqFasJcL8lm4mPTsBl0JgNiN8tQcXM7VCvcH+yDvEyh9vudDjuhpSORqPq\n" +
"f1o/EvJ+gfs269mBnYQujYRvmSd6EAcBntv5zn6amOh03o6PqTY9KaUC/mL9hB84\n" +
"Y5/LYioP16sME7egKnlrGUgKh0ZvGzm7c3SYx3Z5YoeFBOkZajc7Jm+cBw/uBQkF\n" +
"a9mLEczIvOgkq1wto8vr2ptH1gEuvFRcorN3muvq34bk40G08+AHlP3fCLFpI3FA\n" +
"IStJLJZRcO+Ib4sOcKuaBGnuMo/QVOCEMDUs6RgiWtSd93OZKFIUOASVp6YIkcSs\n" +
"5/rmc06sICqBjLfPEB68Jjw=\n" +
"-----END CERTIFICATE-----"),
// Subject: CN=Intermediate CA Cert, O=SomeCompany
// Issuer: CN=Root CA Cert, O=SomeCompany
// Validity: Sun Aug 07 14:37:19 PDT 2016 to Tue Aug 07 14:37:19 PDT 2018
TWO("64",
"CN=Intermediate CA Cert, O=SomeCompany",
"CN=Root CA Cert, O=SomeCompany",
-927189373,
"-----BEGIN CERTIFICATE-----\n" +
"MIIDdjCCAl6gAwIBAgIBZDANBgkqhkiG9w0BAQsFADAtMRQwEgYDVQQKEwtTb21l\n" +
"Q29tcGFueTEVMBMGA1UEAxMMUm9vdCBDQSBDZXJ0MB4XDTE2MDgwNzIxMzcxOVoX\n" +
"DTE4MDgwNzIxMzcxOVowNTEUMBIGA1UEChMLU29tZUNvbXBhbnkxHTAbBgNVBAMT\n" +
"FEludGVybWVkaWF0ZSBDQSBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" +
"CgKCAQEAnJR5CnE7GKlQjigExSJ6hHu302mc0PcA6TDgsIitPYD/r8RBbBuE51OQ\n" +
"7IP7AXmfPUV3/+pO/uxx6mgY5O6XeUl7KadhVPtPcL0BVVevCSOdTMVa3iV4zRpa\n" +
"C6Uy2ouUFnafKnDtlbieggyETUoNgVNJYA9L0XNhtSnENoLHC4Pq0v8OsNtsOWFR\n" +
"NiMTOA49NNDBw85WgPyFAxjqO4z0J0zxdWq3W4rSMB8xrkulv2Rvj3GcfYJK/ab8\n" +
"V1IJ6PMWCpujASY3BzvYPnN7BKuBjbWJPgZdPYfX1cxeG80u0tOuMfWWiNONSMSA\n" +
"7m9y304QA0gKqlrFFn9U4hU89kv1IwIDAQABo4GYMIGVMA8GA1UdEwEB/wQFMAMB\n" +
"Af8wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0\n" +
"OjM5MTM0MB8GA1UdIwQYMBaAFJNMsejEyJUB9tiWycVczvpiMVQZMB0GA1UdDgQW\n" +
"BBRhPnbmXAcIjgKa5azxrumhp4pEnjAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcN\n" +
"AQELBQADggEBAE4nOFdW9OirPnRvxihQXYL9CXLuGQz5tr0XgN8wSY6Un9b6CRiK\n" +
"7obgIGimVdhvUC1qdRcwJqgOfJ2/jR5/5Qo0TVp+ww4dHNdUoj73tagJ7jTu0ZMz\n" +
"5Zdp0uwd4RD/syvTeVcbPc3m4awtgEvRgzpDMcSeKPZWInlo7fbnowKSAUAfO8de\n" +
"0cDkxEBkzPIzGNu256cdLZOqOK9wLJ9mQ0zKgi/2NsldNc2pl/6jkGpA6uL5lJsm\n" +
"fo9sDusWNHV1YggqjDQ19hrf40VuuC9GFl/qAW3marMuEzY/NiKVUxty1q1s48SO\n" +
"g5LoEPDDkbygOt7ICL3HYG1VufhC1Q2YY9c=\n" +
"-----END CERTIFICATE-----"),
// Subject: CN=Root CA Cert, O=SomeCompany
// Issuer: CN=Root CA Cert, O=SomeCompany
// Validity: Fri Jul 08 14:37:18 PDT 2016 to Fri Jun 28 14:37:18 PDT 2019
ROOT_CA("1",
"CN=Root CA Cert, O=SomeCompany",
"CN=Root CA Cert, O=SomeCompany",
-1299818863,
"-----BEGIN CERTIFICATE-----\n" +
"MIIDODCCAiCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMRQwEgYDVQQKEwtTb21l\n" +
"Q29tcGFueTEVMBMGA1UEAxMMUm9vdCBDQSBDZXJ0MB4XDTE2MDcwODIxMzcxOFoX\n" +
"DTE5MDYyODIxMzcxOFowLTEUMBIGA1UEChMLU29tZUNvbXBhbnkxFTATBgNVBAMT\n" +
"DFJvb3QgQ0EgQ2VydDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIlN\n" +
"M3WYEqkU2elXEZrV9QSDbDKwyaLEHafLFciH8Edoag3q/7jEzFJxI7JZ831tdbWQ\n" +
"Bm6Hgo+8pvetOFW1BckL8eIjyOONP2CKfFaeMaozsWi1cgxa+rjpU/Rekc+zBqvv\n" +
"y4Sr97TwT6nQiLlgjC1nCfR1SVpO51qoDChS7n785rsKEZxw/p+kkVWSZffU7zN9\n" +
"c645cPg//L/kjiyeKMkaquGQOYS68gQgy8YZXQv1E3l/8e8Ci1s1DYA5wpCbaBqg\n" +
"Tw84Rr4zlUEQBgXzQlRt+mPzeaDpdG1EeGkXrcdkZ+0EMELoOVXOEn6VNsz6vT3I\n" +
"KrnvQBSnN06xq/iWwC0CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME\n" +
"GDAWgBSTTLHoxMiVAfbYlsnFXM76YjFUGTAdBgNVHQ4EFgQUk0yx6MTIlQH22JbJ\n" +
"xVzO+mIxVBkwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAAi+Nl\n" +
"sxP9t2IhiZIHRJGSBZuQlXIjwYIwbq3ZWc/ApZ+0oxtl7DYQi5uRNt8/opcGNCHc\n" +
"IY0fG93SbkDubXbxPYBW6D/RUjbz59ZryaP5ym55p1MjHTOqy+AM8g41xNTJikc3\n" +
"UUFXXnckeFbawijCsb7vf71owzKuxgBXi9n1rmXXtncKoA/LrUVXoUlKefdgDnsU\n" +
"sl3Q29eibE3HSqziMMoAOLm0jjekFGWIgLeTtyRYR1d0dNaUwsHTrQpPjxxUTn1x\n" +
"sAPpXKfzPnsYAZeeiaaE75GwbWlHzrNinvxdZQd0zctpfBJfVqD/+lWANlw+rOaK\n" +
"J2GyCaJINsyaI/I2\n" +
"-----END CERTIFICATE-----");
public String serialNumber;
public String algorithm;
public String subject;
public String issuer;
public String keyType;
public long certId;
public int keyLength;
public String encoded;
TestCertificate(String serialNumber, String subject, String issuer,
long certId, String encoded) {
this.serialNumber = serialNumber;
this.subject = subject;
this.issuer = issuer;
this.algorithm = "SHA256withRSA";
this.encoded = encoded;
this.certId = certId;
this.keyType = "RSA";
this.keyLength = 2048;
}
public X509Certificate generate(CertificateFactory cf) throws CertificateException {
ByteArrayInputStream is = new ByteArrayInputStream(encoded.getBytes());
return (X509Certificate) cf.generateCertificate(is);
}
public static void generateChain(boolean selfSignedTest) throws Exception {
// Do path validation as if it is always Tue, 06 Sep 2016 22:12:21 GMT
// This value is within the lifetimes of all certificates.
Date testDate = new Date(1473199941000L);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate c1 = TestCertificate.ONE.generate(cf);
X509Certificate c2 = TestCertificate.TWO.generate(cf);
X509Certificate ca = TestCertificate.ROOT_CA.generate(cf);
TrustAnchor ta = new TrustAnchor(ca, null);
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
PKIXParameters params = new PKIXParameters(Collections.singleton(ta));
params.setRevocationEnabled(false);
params.setDate(testDate);
if (!selfSignedTest) {
CertPath path = cf.generateCertPath(List.of(c1, c2));
validator.validate(path, params);
} else {
CertPath path = cf.generateCertPath(List.of(ca));
validator.validate(path, params);
}
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.test.lib.security;
import java.io.*;
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 HASHCODE = -1057291798L;
public static final long ANCHOR_HASHCODE = 1688661792L;
public static final String CERT_SERIAL = "edbec8f705af2514";
public static final String ANCHOR_CERT_SERIAL = "8e191778b2f331be";
public String protocolVersion;
public String peerHost;
public int peerPort;
@Override
protected void runServerApplication(SSLSocket socket) throws Exception {
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();
sslIS.read();
sslOS.write(85);
sslOS.flush();
}
@Override
protected void runClientApplication(SSLSocket socket) throws Exception {
socket.setEnabledCipherSuites(new String[] { CIPHER_SUITE });
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();
sslOS.write(280);
sslOS.flush();
sslIS.read();
SSLSession sslSession = socket.getSession();
protocolVersion = sslSession.getProtocol();
peerHost = sslSession.getPeerHost();
peerPort = sslSession.getPeerPort();
}
}