2929import io .netty .channel .EventLoopGroup ;
3030import io .netty .handler .ssl .SslContext ;
3131import io .netty .handler .ssl .SslContextBuilder ;
32+ import org .slf4j .Logger ;
33+ import org .slf4j .LoggerFactory ;
34+
3235import java .io .IOException ;
3336import java .net .URI ;
3437import java .net .URISyntaxException ;
3538import java .net .URLDecoder ;
3639import java .security .KeyManagementException ;
40+ import java .security .KeyStore ;
41+ import java .security .KeyStoreException ;
3742import java .security .NoSuchAlgorithmException ;
3843import java .time .Duration ;
3944import java .util .*;
4752import javax .net .ssl .SSLContext ;
4853import javax .net .ssl .SSLSocketFactory ;
4954import javax .net .ssl .TrustManager ;
50- import org .slf4j .Logger ;
51- import org .slf4j .LoggerFactory ;
55+ import javax .net .ssl .TrustManagerFactory ;
5256
5357/**
5458 * Convenience factory class to facilitate opening a {@link Connection} to a RabbitMQ node.
@@ -348,8 +352,7 @@ public void setVirtualHost(String virtualHost) {
348352 *
349353 * @param uri is the AMQP URI containing the data
350354 */
351- public void setUri (URI uri )
352- throws URISyntaxException , NoSuchAlgorithmException , KeyManagementException {
355+ public void setUri (URI uri ) throws NoSuchAlgorithmException , KeyManagementException {
353356 if ("amqp" .equals (uri .getScheme ().toLowerCase ())) {
354357 setPort (DEFAULT_AMQP_PORT );
355358 } else if ("amqps" .equals (uri .getScheme ().toLowerCase ())) {
@@ -807,12 +810,11 @@ public boolean isSSL() {
807810 }
808811
809812 /**
810- * Convenience method for configuring TLS using the default set of TLS protocols and a trusting
811- * TrustManager. This setup is <strong>only suitable for development and QA environments</strong>.
812- * The trust manager will <strong>trust every server certificate presented</strong> to it, this is
813- * convenient for local development but <strong>not recommended to use in production</strong> as
814- * it provides no protection against man-in-the-middle attacks. Prefer {@link
815- * #useSslProtocol(SSLContext)}.
813+ * Convenience method for configuring TLS using the JVM default trust store and with hostname
814+ * verification enabled. This is the recommended method for enabling TLS in production
815+ * environments.
816+ *
817+ * <p>Use {@link #useSslProtocol(SSLContext)} for more control over the {@link SSLContext}.
816818 *
817819 * <p>Note this method has NO effect when using Netty, use {@link
818820 * com.rabbitmq.client.ConnectionFactory.NettyConfiguration#sslContext(io.netty.handler.ssl.SslContext)}
@@ -822,19 +824,16 @@ public void useSslProtocol() throws NoSuchAlgorithmException, KeyManagementExcep
822824 useSslProtocol (
823825 computeDefaultTlsProtocol (
824826 SSLContext .getDefault ().getSupportedSSLParameters ().getProtocols ()));
827+ useSslProtocol (SSLContext .getDefault ());
825828 }
826829
827830 /**
828- * Convenience method for configuring TLS using the supplied protocol and a very trusting
829- * TrustManager. This setup is <strong>only suitable for development and QA environments</strong>.
830- * The trust manager <strong>will trust every server certificate presented</strong> to it, this is
831- * convenient for local development but not recommended to use in production as it
832- * <strong>provides no protection against man-in-the-middle attacks</strong>.
831+ * Convenience method for configuring TLS using the supplied protocol, the JVM default trust
832+ * store, and with hostname verification enabled.
833833 *
834- * <p>Use {@link #useSslProtocol(SSLContext)} in production environments. The produced {@link
835- * SSLContext} instance will be shared by all the connections created by this connection factory.
836- *
837- * <p>Use {@link #setSslContextFactory(SslContextFactory)} for more flexibility.
834+ * <p>The produced {@link SSLContext} instance will be shared by all the connections created by
835+ * this connection factory. Use {@link #setSslContextFactory(SslContextFactory)} for more
836+ * flexibility.
838837 *
839838 * <p>Note this method has NO effect when using Netty, use {@link
840839 * com.rabbitmq.client.ConnectionFactory.NettyConfiguration#sslContext(io.netty.handler.ssl.SslContext)}
@@ -844,7 +843,16 @@ public void useSslProtocol() throws NoSuchAlgorithmException, KeyManagementExcep
844843 */
845844 public void useSslProtocol (String protocol )
846845 throws NoSuchAlgorithmException , KeyManagementException {
847- useSslProtocol (protocol , new TrustEverythingTrustManager ());
846+ try {
847+ TrustManagerFactory tmf =
848+ TrustManagerFactory .getInstance (TrustManagerFactory .getDefaultAlgorithm ());
849+ tmf .init ((KeyStore ) null );
850+ SSLContext c = SSLContext .getInstance (protocol );
851+ c .init (null , tmf .getTrustManagers (), null );
852+ this .useSslProtocol (c );
853+ } catch (KeyStoreException e ) {
854+ throw new KeyManagementException ("Failed to initialize default trust manager" , e );
855+ }
848856 }
849857
850858 /**
@@ -889,6 +897,26 @@ public void useSslProtocol(String protocol, TrustManager trustManager)
889897 public void useSslProtocol (SSLContext context ) {
890898 this .sslContextFactory = name -> context ;
891899 setSocketFactory (context .getSocketFactory ());
900+ this .enableHostnameVerification ();
901+ }
902+
903+ /**
904+ * Configure TLS without any certificate or hostname verification.
905+ *
906+ * <p><strong>DO NOT USE IN PRODUCTION.</strong> This disables all server authentication and
907+ * provides no protection against man-in-the-middle attacks. Use only in local development or CI
908+ * environments where the broker identity is not sensitive.
909+ *
910+ * <p>Note this method has NO effect when using Netty, use {@link
911+ * com.rabbitmq.client.ConnectionFactory.NettyConfiguration#useTlsWithNoVerification()} instead.
912+ */
913+ public void useTlsWithNoVerification ()
914+ throws NoSuchAlgorithmException , KeyManagementException {
915+ logTlsNoVerificationWarning ();
916+ this .useSslProtocol (
917+ computeDefaultTlsProtocol (
918+ SSLContext .getDefault ().getSupportedSSLParameters ().getProtocols ()),
919+ new TrustEverythingTrustManager ());
892920 }
893921
894922 /**
@@ -1569,6 +1597,22 @@ public ConnectionFactory connectionFactory() {
15691597 return this .cf ;
15701598 }
15711599
1600+ /**
1601+ * Configure TLS without any certificate or hostname verification.
1602+ *
1603+ * <p><strong>DO NOT USE IN PRODUCTION.</strong> This disables all server authentication and
1604+ * provides no protection against man-in-the-middle attacks. Use only in local development or CI
1605+ * environments where the broker identity is not sensitive.
1606+ */
1607+ public NettyConfiguration useTlsWithNoVerification () throws Exception {
1608+ logTlsNoVerificationWarning ();
1609+ return sslContext (
1610+ SslContextBuilder .forClient ()
1611+ .trustManager (new TrustEverythingTrustManager ())
1612+ .endpointIdentificationAlgorithm (null )
1613+ .build ());
1614+ }
1615+
15721616 private boolean isTls () {
15731617 return this .sslContextFactory != null ;
15741618 }
@@ -1874,6 +1918,7 @@ public int getChannelRpcTimeout() {
18741918 */
18751919 public void setSslContextFactory (SslContextFactory sslContextFactory ) {
18761920 this .sslContextFactory = sslContextFactory ;
1921+ this .enableHostnameVerification ();
18771922 }
18781923
18791924 /**
@@ -1986,4 +2031,13 @@ public static int ensureUnsignedShort(int value) {
19862031 return value ;
19872032 }
19882033 }
2034+
2035+ static void logTlsNoVerificationWarning () {
2036+ LoggerFactory .getLogger ("com.rabbitmq.client.security" ).warn (
2037+ "SECURITY ALERT: this mode trusts every certificate, effectively disabling peer verification, " +
2038+ "and disables hostname verification. " +
2039+ "This is convenient for local development but offers no protection against man-in-the-middle attacks. " +
2040+ "Please see https://www.rabbitmq.com/ssl.html to learn more about peer certificate verification."
2041+ );
2042+ }
19892043}
0 commit comments