CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-netflix-ribbon--ribbon-core

Client configuration APIs and shared utilities for Netflix's Ribbon IPC library, providing core interfaces for load balancing, fault tolerance, and service discovery capabilities in cloud environments.

Pending
Overview
Eval results
Files

ssl-support.mddocs/

SSL Security

SSL context factories for secure communication with support for custom keystores and truststores. The SSL framework provides flexible certificate management and secure connection establishment for client applications.

Capabilities

AbstractSslContextFactory

Abstract base class for SSL context creation with keystore and truststore support.

/**
 * Abstract base class for SSL context creation with keystore and truststore support
 */
public abstract class AbstractSslContextFactory {
    /**
     * Default socket algorithm constant
     */
    public static final String SOCKET_ALGORITHM = "SSL";
    
    /**
     * Protected constructor for SSL context factory
     * @param trustStore the truststore containing trusted certificates
     * @param trustStorePassword password for the truststore
     * @param keyStore the keystore containing client certificates and private keys
     * @param keyStorePassword password for the keystore
     */
    protected AbstractSslContextFactory(KeyStore trustStore, String trustStorePassword, 
                                       KeyStore keyStore, String keyStorePassword);
    
    /**
     * Gets the keystore
     * @return the keystore used by this factory
     */
    public KeyStore getKeyStore();
    
    /**
     * Gets the truststore
     * @return the truststore used by this factory
     */
    public KeyStore getTrustStore();
    
    /**
     * Gets keystore password length
     * @return length of the keystore password (for security validation)
     */
    public int getKeyStorePasswordLength();
    
    /**
     * Gets truststore password length
     * @return length of the truststore password (for security validation)
     */
    public int getTrustStorePasswordLength();
    
    /**
     * Creates SSL context
     * @return configured SSLContext ready for use
     * @throws ClientSslSocketFactoryException if SSL context creation fails
     */
    public SSLContext getSSLContext() throws ClientSslSocketFactoryException;
}

URLSslContextFactory

SSL context factory that loads keystores from URLs.

/**
 * SSL context factory that loads keystores from URLs
 */
public class URLSslContextFactory extends AbstractSslContextFactory {
    /**
     * Creates SSL context factory loading keystores from URLs
     * @param trustStoreUrl URL to the truststore file
     * @param trustStorePassword password for the truststore
     * @param keyStoreUrl URL to the keystore file
     * @param keyStorePassword password for the keystore
     * @throws ClientSslSocketFactoryException if keystore loading fails
     */
    public URLSslContextFactory(URL trustStoreUrl, String trustStorePassword,
                               URL keyStoreUrl, String keyStorePassword) 
                               throws ClientSslSocketFactoryException;
    
    /**
     * String representation of the factory
     * @return string describing this SSL factory configuration
     */
    public String toString();
}

Usage Examples:

import com.netflix.client.ssl.*;
import javax.net.ssl.SSLContext;
import java.net.URL;
import java.security.KeyStore;

// Creating SSL context factory from URLs
try {
    URL trustStoreUrl = new URL("file:///path/to/truststore.jks");
    URL keyStoreUrl = new URL("file:///path/to/keystore.jks");
    
    URLSslContextFactory factory = new URLSslContextFactory(
        trustStoreUrl, "truststore-password",
        keyStoreUrl, "keystore-password"
    );
    
    SSLContext sslContext = factory.getSSLContext();
    
    // Use SSL context for secure connections
    configureHttpsClient(sslContext);
    
} catch (ClientSslSocketFactoryException e) {
    logger.error("Failed to create SSL context", e);
    // Fall back to default SSL configuration
}

// Loading from classpath resources
URL trustStoreUrl = getClass().getResource("/ssl/truststore.jks");
URL keyStoreUrl = getClass().getResource("/ssl/client-keystore.jks");

URLSslContextFactory factory = new URLSslContextFactory(
    trustStoreUrl, System.getProperty("ssl.truststore.password"),
    keyStoreUrl, System.getProperty("ssl.keystore.password")
);

Custom SSL Context Factory Implementation

/**
 * Example custom SSL context factory for specific certificate management needs
 */
public class CustomSslContextFactory extends AbstractSslContextFactory {
    private final String certificateAlias;
    
    public CustomSslContextFactory(KeyStore trustStore, String trustStorePassword,
                                  KeyStore keyStore, String keyStorePassword,
                                  String certificateAlias) {
        super(trustStore, trustStorePassword, keyStore, keyStorePassword);
        this.certificateAlias = certificateAlias;
    }
    
    @Override
    public SSLContext getSSLContext() throws ClientSslSocketFactoryException {
        try {
            // Create SSL context with custom certificate selection
            SSLContext context = SSLContext.getInstance("TLS");
            
            // Initialize with custom key manager that uses specific certificate alias
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(getKeyStore(), getKeyStorePassword().toCharArray());
            
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(getTrustStore());
            
            context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
            
            return context;
            
        } catch (Exception e) {
            throw new ClientSslSocketFactoryException("Failed to create custom SSL context", e);
        }
    }
    
    private String getKeyStorePassword() {
        // Custom password retrieval logic
        return System.getProperty("client.keystore.password");
    }
}

SSL Configuration Patterns

/**
 * SSL configuration manager for different environments
 */
public class SslConfigurationManager {
    private static final Logger logger = LoggerFactory.getLogger(SslConfigurationManager.class);
    
    /**
     * Creates SSL context factory for production environment
     */
    public static AbstractSslContextFactory createProductionFactory() 
            throws ClientSslSocketFactoryException {
        try {
            // Load from secure configuration
            URL trustStoreUrl = new URL(System.getProperty("ssl.truststore.url"));
            URL keyStoreUrl = new URL(System.getProperty("ssl.keystore.url"));
            
            String trustStorePassword = System.getProperty("ssl.truststore.password");
            String keyStorePassword = System.getProperty("ssl.keystore.password");
            
            return new URLSslContextFactory(trustStoreUrl, trustStorePassword,
                                          keyStoreUrl, keyStorePassword);
                                          
        } catch (Exception e) {
            throw new ClientSslSocketFactoryException("Failed to create production SSL factory", e);
        }
    }
    
    /**
     * Creates SSL context factory for development environment
     */
    public static AbstractSslContextFactory createDevelopmentFactory() 
            throws ClientSslSocketFactoryException {
        try {
            // Load from classpath for development
            URL trustStoreUrl = SslConfigurationManager.class.getResource("/ssl/dev-truststore.jks");
            URL keyStoreUrl = SslConfigurationManager.class.getResource("/ssl/dev-keystore.jks");
            
            return new URLSslContextFactory(trustStoreUrl, "dev-password",
                                          keyStoreUrl, "dev-password");
                                          
        } catch (Exception e) {
            throw new ClientSslSocketFactoryException("Failed to create development SSL factory", e);
        }
    }
    
    /**
     * Creates SSL context factory with validation
     */
    public static AbstractSslContextFactory createValidatedFactory(
            URL trustStoreUrl, String trustStorePassword,
            URL keyStoreUrl, String keyStorePassword) throws ClientSslSocketFactoryException {
        
        // Validate inputs
        if (trustStoreUrl == null || keyStoreUrl == null) {
            throw new ClientSslSocketFactoryException("SSL store URLs cannot be null", null);
        }
        
        if (trustStorePassword == null || keyStorePassword == null) {
            throw new ClientSslSocketFactoryException("SSL store passwords cannot be null", null);
        }
        
        // Validate password strength (basic check)
        if (trustStorePassword.length() < 6 || keyStorePassword.length() < 6) {
            logger.warn("SSL store passwords are weak (less than 6 characters)");
        }
        
        URLSslContextFactory factory = new URLSslContextFactory(
            trustStoreUrl, trustStorePassword,
            keyStoreUrl, keyStorePassword
        );
        
        // Validate that SSL context can be created
        SSLContext context = factory.getSSLContext();
        logger.info("SSL context created successfully: {}", factory.toString());
        
        return factory;
    }
}

Integration with Client Configuration

/**
 * Client with SSL support integration
 */
public class SecureClient {
    private final SSLContext sslContext;
    private final IClientConfig config;
    
    public SecureClient(IClientConfig config) throws ClientSslSocketFactoryException {
        this.config = config;
        this.sslContext = createSslContext(config);
    }
    
    private SSLContext createSslContext(IClientConfig config) throws ClientSslSocketFactoryException {
        try {
            // Get SSL configuration from client config
            String trustStoreLocation = config.get(CommonClientConfigKey.TrustStore);
            String trustStorePassword = config.get(CommonClientConfigKey.TrustStorePassword);
            String keyStoreLocation = config.get(CommonClientConfigKey.KeyStore);
            String keyStorePassword = config.get(CommonClientConfigKey.KeyStorePassword);
            
            if (trustStoreLocation != null && keyStoreLocation != null) {
                // Create factory from configuration
                URL trustStoreUrl = new URL(trustStoreLocation);
                URL keyStoreUrl = new URL(keyStoreLocation);
                
                URLSslContextFactory factory = new URLSslContextFactory(
                    trustStoreUrl, trustStorePassword,
                    keyStoreUrl, keyStorePassword
                );
                
                return factory.getSSLContext();
            } else {
                // Use default SSL context
                return SSLContext.getDefault();
            }
            
        } catch (Exception e) {
            throw new ClientSslSocketFactoryException("Failed to create SSL context from configuration", e);
        }
    }
    
    public void executeSecureRequest(ClientRequest request) throws Exception {
        // Use SSL context for secure communication
        if (request.getUri().getScheme().equals("https")) {
            // Configure HTTPS connection with SSL context
            configureHttpsConnection(sslContext);
        }
        
        // Execute request
    }
    
    private void configureHttpsConnection(SSLContext sslContext) {
        // Configure HTTPS connection to use the SSL context
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
    }
}

SSL Troubleshooting and Validation

/**
 * SSL diagnostic utilities
 */
public class SslDiagnostics {
    private static final Logger logger = LoggerFactory.getLogger(SslDiagnostics.class);
    
    /**
     * Validates SSL factory configuration
     */
    public static void validateSslFactory(AbstractSslContextFactory factory) {
        try {
            logger.info("Validating SSL factory: {}", factory.toString());
            
            // Check keystore
            KeyStore keyStore = factory.getKeyStore();
            if (keyStore != null) {
                logger.info("Keystore loaded with {} entries", keyStore.size());
                logKeyStoreAliases(keyStore);
            } else {
                logger.warn("No keystore configured");
            }
            
            // Check truststore
            KeyStore trustStore = factory.getTrustStore();
            if (trustStore != null) {
                logger.info("Truststore loaded with {} entries", trustStore.size());
                logTrustStoreAliases(trustStore);
            } else {
                logger.warn("No truststore configured");
            }
            
            // Validate password lengths
            int keyStorePasswordLength = factory.getKeyStorePasswordLength();
            int trustStorePasswordLength = factory.getTrustStorePasswordLength();
            
            logger.info("Keystore password length: {}", keyStorePasswordLength);
            logger.info("Truststore password length: {}", trustStorePasswordLength);
            
            // Test SSL context creation
            SSLContext context = factory.getSSLContext();
            logger.info("SSL context created successfully: {}", context.getProtocol());
            
        } catch (Exception e) {
            logger.error("SSL factory validation failed", e);
        }
    }
    
    private static void logKeyStoreAliases(KeyStore keyStore) {
        try {
            Enumeration<String> aliases = keyStore.aliases();
            while (aliases.hasMoreElements()) {
                String alias = aliases.nextElement();
                boolean isKey = keyStore.isKeyEntry(alias);
                boolean isCert = keyStore.isCertificateEntry(alias);
                logger.debug("Keystore alias: {} (key: {}, cert: {})", alias, isKey, isCert);
            }
        } catch (Exception e) {
            logger.warn("Could not enumerate keystore aliases", e);
        }
    }
    
    private static void logTrustStoreAliases(KeyStore trustStore) {
        try {
            Enumeration<String> aliases = trustStore.aliases();
            while (aliases.hasMoreElements()) {
                String alias = aliases.nextElement();
                logger.debug("Truststore alias: {}", alias);
            }
        } catch (Exception e) {
            logger.warn("Could not enumerate truststore aliases", e);
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-com-netflix-ribbon--ribbon-core

docs

client-framework.md

configuration.md

exceptions.md

index.md

retry-handlers.md

ssl-support.md

tile.json