diff --git a/Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java b/Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java index 9fc5458dee..088c970198 100644 --- a/Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java +++ b/Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java @@ -66,6 +66,8 @@ import utility.application.ApplicationLayout; */ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHandle { + private final static String TLS_SERVER_PROTOCOLS_PROPERTY = "ghidra.tls.server.protocols"; + private static SslRMIServerSocketFactory serverSocketFactory; private static SslRMIClientSocketFactory clientSocketFactory; private static InetAddress bindAddress; @@ -786,17 +788,19 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan log.info( " Anonymous server access: " + (allowAnonymousAccess ? "enabled" : "disabled")); - log.info(SystemUtilities.getUserName() + " starting Ghidra Server..."); - - serverSocketFactory = new SslRMIServerSocketFactory(null, null, authMode == PKI_LOGIN) { + serverSocketFactory = new SslRMIServerSocketFactory(null, getEnabledTlsProtocols(), + authMode == PKI_LOGIN) { @Override public ServerSocket createServerSocket(int port) throws IOException { return new GhidraSSLServerSocket(port, bindAddress, getEnabledCipherSuites(), getEnabledProtocols(), getNeedClientAuth()); } + }; clientSocketFactory = new SslRMIClientSocketFactory(); + log.info(SystemUtilities.getUserName() + " starting Ghidra Server..."); + GhidraServer svr = new GhidraServer(serverRoot, authMode, loginDomain, nameCallbackAllowed, altSSHLoginAllowed, defaultPasswordExpiration, allowAnonymousAccess, autoProvision, jaasConfigFile); @@ -821,6 +825,21 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan } } + private static String[] getEnabledTlsProtocols() { + String protocolList = System.getProperty(TLS_SERVER_PROTOCOLS_PROPERTY); + if (protocolList != null) { + + log.info(" Enabled protocols: " + protocolList); + + String[] protocols = protocolList.split(";"); + for (int i = 0; i < protocols.length; i++) { + protocols[i] = protocols[i].trim(); + } + return protocols; + } + return null; + } + static synchronized void stop() { if (server == null) { throw new IllegalStateException("Invalid Stop request, Server is not running"); diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/net/SSLContextInitializer.java b/Ghidra/Framework/Generic/src/main/java/ghidra/net/SSLContextInitializer.java index 3708f05ed4..fd74f17fa2 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/net/SSLContextInitializer.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/net/SSLContextInitializer.java @@ -24,31 +24,25 @@ import ghidra.framework.ModuleInitializer; import ghidra.util.Msg; /** - * Initialize the default SSLContext for use by SSL connections (e.g., https). + * Initialize the default SSLContext for use by all SSL connections (e.g., https). * It is the responsibility of the Application to properly invoke this initializer - * so that the default SSLContext may be established. While HTTPS URL connections + * to ensure that the default SSLContext is properly established. While HTTPS URL connections * will make use of this default SSLContext, other SSL connections may need to * specify the {@link ApplicationSSLSocketFactory} to leverage the applications * default SSLContext. + *
+ * The property jdk.tls.client.protocols should be set to restrict secure
+ * client connections to a specific set of enabled TLS protocols (e.g., TLSv1.2,TLSv1.3).
+ * See JDK and JRE Cryptographic Algorithms
+ * for details.
+ *
* @see ApplicationTrustManagerFactory
* @see ApplicationKeyManagerFactory
* @see ApplicationKeyManagerUtils
*/
public class SSLContextInitializer implements ModuleInitializer {
- // NOTE: specifying a default protocol of "TLS" will defer the default
- // protocol selection to the underlying protocol implementation.
- // The protocol may be specified as a comma-separated list of protocol
- // versions where the leftmost takes precendence during the initial
- // negotiation. The Java security policy may be modified to disable
- // the use of specific protocols via the jdk.tls.disabledAlgorithms
- // property. The security property file is located within the
- // java installation at jre/lib/security/java.security
-
- // Default list of allowed TLS protocols for outbound connections
- private static final String DEFAULT_TLS_PROTOCOL = "TLS";
-
- private static final String PROTOCOL_PROPERTY = "ghidra.net.ssl.protocol";
+ private static final String DEFAULT_SSL_PROTOCOL = "TLS";
private static SSLContext sslContext;
@@ -68,17 +62,6 @@ public class SSLContextInitializer implements ModuleInitializer {
return initialize();
}
- private static String getSSLProtocol() {
- String value = System.getProperty(PROTOCOL_PROPERTY);
- if (value != null) {
- value = value.trim();
- if (value.length() != 0) {
- return value;
- }
- }
- return DEFAULT_TLS_PROTOCOL;
- }
-
/**
* Initialize default SSLContext
* @return true if successful, else false (see logged error)
@@ -95,8 +78,8 @@ public class SSLContextInitializer implements ModuleInitializer {
KeyManager[] keyManagers = ApplicationKeyManagerFactory.getInstance().getKeyManagers();
try {
-
- sslContext = SSLContext.getInstance(getSSLProtocol());
+ // Use new instance of SSLContext to avoid adopting CA certs provided with Java
+ sslContext = SSLContext.getInstance(DEFAULT_SSL_PROTOCOL);
SecureRandom random = SecureRandomFactory.getSecureRandom();
sslContext.init(keyManagers, ApplicationTrustManagerFactory.getTrustManagers(), random);
SSLContext.setDefault(sslContext);
diff --git a/Ghidra/RuntimeScripts/Common/server/server.conf b/Ghidra/RuntimeScripts/Common/server/server.conf
index 780da9a0c8..d93760510c 100644
--- a/Ghidra/RuntimeScripts/Common/server/server.conf
+++ b/Ghidra/RuntimeScripts/Common/server/server.conf
@@ -29,33 +29,37 @@ wrapper.java.additional.2=-DApplicationRollingFileAppender.maxBackupIndex=10
# Ensure that classpath_frag is defined for service startup
wrapper.java.additional.3=-Dclasspath_frag=${classpath_frag}
+# Limit server to specific TLS protocols for all secure connections.
+# NOTE: multiple protocols must be separated with a semi-colon (e.g., TLSv1.2;TLSv1.3).
+wrapper.java.additional.4=-Dghidra.tls.server.protocols=TLSv1.2;TLSv1.3
+
# A suitable cacerts file must be installed when using PKI authentication
-#wrapper.java.additional.4=-Dghidra.cacerts=./Ghidra/cacerts
+#wrapper.java.additional.5=-Dghidra.cacerts=./Ghidra/cacerts
# If Ghidra clients must authenticate the server, the server will need to install
# a server key/certificate in a secure location (e.g., /etc/pki/...)
# and specify the location and password via the properties below.
# Be sure to properly set permissions on the Ghidra installation and this file
# if using these settings.
-#wrapper.java.additional.5=-Dghidra.keystore=
-#wrapper.java.additional.6=-Dghidra.password=
+#wrapper.java.additional.6=-Dghidra.keystore=
+#wrapper.java.additional.7=-Dghidra.password=
# Temporary Directory Setting - uncomment the following setting to override the Java default.
# This may be necessary on certain Windows platforms when installing as a service.
-#wrapper.java.additional.7=-Djava.io.tmpdir=C:\\Windows\\Temp
+#wrapper.java.additional.8=-Djava.io.tmpdir=C:\\Windows\\Temp
# Enable/Disable use of compression for DataBuffer serialization and Block Streams
-wrapper.java.additional.8=-Ddb.buffers.DataBuffer.compressedOutput=true
+wrapper.java.additional.9=-Ddb.buffers.DataBuffer.compressedOutput=true
# Uncomment to enable remote debug support
# The debug address will listen on all network interfaces, if desired the '*' may be
# set to a specific interface IP address (e.g., 127.0.0.1) if you wish to restrict.
# During debug it may be necessary to increase timeout values to prevent the wrapper
# from restarting the server due to unresponsiveness.
-#wrapper.java.additional.9=-Xdebug
-#wrapper.java.additional.10=-Xnoagent
-#wrapper.java.additional.11=-Djava.compiler=NONE
-#wrapper.java.additional.12=-Xrunjdwp:transport=dt_socket\,server=y\,suspend=n\,address=*:18200
+#wrapper.java.additional.10=-Xdebug
+#wrapper.java.additional.11=-Xnoagent
+#wrapper.java.additional.12=-Djava.compiler=NONE
+#wrapper.java.additional.13=-Xrunjdwp:transport=dt_socket\,server=y\,suspend=n\,address=*:18200
#wrapper.startup.timeout=0
#wrapper.ping.timeout=0
@@ -66,10 +70,10 @@ wrapper.java.additional.8=-Ddb.buffers.DataBuffer.compressedOutput=true
# Uncomment to enable remote use of jvisualvm for profiling
# See JMX documentation for more information: http://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html
-#wrapper.java.additional.13=-Dcom.sun.management.jmxremote.port=9010
-#wrapper.java.additional.14=-Dcom.sun.management.jmxremote.local.only=false
-#wrapper.java.additional.15=-Dcom.sun.management.jmxremote.authenticate=false
-#wrapper.java.additional.16=-Dcom.sun.management.jmxremote.ssl=false
+#wrapper.java.additional.14=-Dcom.sun.management.jmxremote.port=9010
+#wrapper.java.additional.15=-Dcom.sun.management.jmxremote.local.only=false
+#wrapper.java.additional.16=-Dcom.sun.management.jmxremote.authenticate=false
+#wrapper.java.additional.17=-Dcom.sun.management.jmxremote.ssl=false
# YAJSW will by default assume a POSIX spawn for Linux and Mac OS X systems, unfortunately it has
# not yet been implemented for Mac OS X. The default process support within YAJSW for Mac OS X is
diff --git a/Ghidra/RuntimeScripts/Common/support/launch.properties b/Ghidra/RuntimeScripts/Common/support/launch.properties
index 914085dbe6..b427d091b0 100644
--- a/Ghidra/RuntimeScripts/Common/support/launch.properties
+++ b/Ghidra/RuntimeScripts/Common/support/launch.properties
@@ -24,29 +24,17 @@ VMARGS_LINUX=-Dsun.java2d.uiScale=1
VMARGS_LINUX=-Dawt.useSystemAAFontSettings=on
VMARGS_WINDOWS=-Dsun.java2d.d3d=false
-# Set acceptable TLS protocol version(s) for outbound client SSL connections.
-# The Ghidra application establishes the default SSLContext based upon
-# this list of acceptable protocols. Omiting this property setting or
-# simply specifying TLS without a version will defer to the underlying TLS
-# protocol implementation and its preferred defaults. During the connection
-# handshake both sides will agree upon a preferred protocol. The default
-# SSLContext established within Ghidra is intended to support all
-# Ghidra Servers client connections and other SSL-based
-# network connections such as https, although it is possible for a
-# connection-specific SSLContext to be established which bypasses this
-# setting (e.g., log4j, bndlib).
-#VMARGS=-Dghidra.net.ssl.protocol=TLSv1.3,TLSv1.2
+# The Ghidra application establishes the default SSLContext for all
+# secure client connections based upon Java's default TLS protocol enablement.
+# Setting this property will restrict the enabled TLS protocol versions for
+# all secure network connections. Specifying multiple protocols must be
+# comma-separated (e.g., TLSv1.2,TLSv1.3). See https://java.com/en/configure_crypto.html
+# for details on configuring Java's cryptographic algorithms.
+VMARGS=-Djdk.tls.client.protocols=TLSv1.2,TLSv1.3
-# Set acceptable HTTPS protocols for outbound HTTPS client connections for those
-# cases which do not use the default SSLContext and associated socket factory
-# (e.g., Apache HttpClientBuilder). Specifying TLS without a version will defer
-# to the underlying TLS protocol implementation.
-#VMARGS=-Dhttps.protocols=TLSv1.3,TLSv1.2
-VMARGS=-Dhttps.protocols=TLS
-
-# Force PKI authentication of all HTTPS and Ghidra Server connections (i.e.,
-# server authentication)
-VMARGS=-Dghidra.cacerts=
+# Force PKI server authentication of all HTTPS and Ghidra Server connections by
+# specifying path to installed CA certificates file.
+# VMARGS=-Dghidra.cacerts=
# The following property will limit the number of processor cores that Ghidra
# will use for thread pools. If not specified, it will use the default number