001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2010 Sun Microsystems, Inc. 025 */ 026 027package org.forgerock.opendj.ldap; 028 029import java.security.GeneralSecurityException; 030import java.security.Provider; 031import java.security.SecureRandom; 032 033import javax.net.ssl.KeyManager; 034import javax.net.ssl.SSLContext; 035import javax.net.ssl.TrustManager; 036 037/** 038 * An SSL context builder provides an interface for incrementally constructing 039 * {@link SSLContext} instances for use when securing connections with SSL or 040 * the StartTLS extended operation. The {@link #getSSLContext()} should be 041 * called in order to obtain the {@code SSLContext}. 042 * <p> 043 * For example, use the SSL context builder when setting up LDAP options needed 044 * to use StartTLS. {@link org.forgerock.opendj.ldap.TrustManagers 045 * TrustManagers} has methods you can use to set the trust manager for the SSL 046 * context builder. 047 * 048 * <pre> 049 * LDAPOptions options = new LDAPOptions(); 050 * SSLContext sslContext = 051 * new SSLContextBuilder().setTrustManager(...).getSSLContext(); 052 * options.setSSLContext(sslContext); 053 * options.setUseStartTLS(true); 054 * 055 * String host = ...; 056 * int port = ...; 057 * LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port, options); 058 * Connection connection = factory.getConnection(); 059 * // Connection uses StartTLS... 060 * </pre> 061 */ 062public final class SSLContextBuilder { 063 064 /** 065 * SSL protocol: supports some version of SSL; may support other versions. 066 */ 067 public static final String PROTOCOL_SSL = "SSL"; 068 069 /** 070 * SSL protocol: supports SSL version 2 or higher; may support other 071 * versions. 072 */ 073 public static final String PROTOCOL_SSL2 = "SSLv2"; 074 075 /** 076 * SSL protocol: supports SSL version 3; may support other versions. 077 */ 078 public static final String PROTOCOL_SSL3 = "SSLv3"; 079 080 /** 081 * SSL protocol: supports some version of TLS; may support other versions. 082 */ 083 public static final String PROTOCOL_TLS = "TLS"; 084 085 /** 086 * SSL protocol: supports RFC 2246: TLS version 1.0 ; may support other 087 * versions. 088 */ 089 public static final String PROTOCOL_TLS1 = "TLSv1"; 090 091 /** 092 * SSL protocol: supports RFC 4346: TLS version 1.1 ; may support other 093 * versions. 094 */ 095 public static final String PROTOCOL_TLS1_1 = "TLSv1.1"; 096 097 private TrustManager trustManager; 098 private KeyManager keyManager; 099 private String protocol = PROTOCOL_TLS1; 100 private SecureRandom random; 101 102 /** These are mutually exclusive. */ 103 private Provider provider; 104 private String providerName; 105 106 /** 107 * Creates a new SSL context builder using default parameters. 108 */ 109 public SSLContextBuilder() { 110 // Do nothing. 111 } 112 113 /** 114 * Creates a {@code SSLContext} using the parameters of this SSL context 115 * builder. 116 * 117 * @return A {@code SSLContext} using the parameters of this SSL context 118 * builder. 119 * @throws GeneralSecurityException 120 * If the SSL context could not be created, perhaps due to 121 * missing algorithms. 122 */ 123 public SSLContext getSSLContext() throws GeneralSecurityException { 124 TrustManager[] tm = null; 125 if (trustManager != null) { 126 tm = new TrustManager[] { trustManager }; 127 } 128 129 KeyManager[] km = null; 130 if (keyManager != null) { 131 km = new KeyManager[] { keyManager }; 132 } 133 134 SSLContext sslContext; 135 if (provider != null) { 136 sslContext = SSLContext.getInstance(protocol, provider); 137 } else if (providerName != null) { 138 sslContext = SSLContext.getInstance(protocol, providerName); 139 } else { 140 sslContext = SSLContext.getInstance(protocol); 141 } 142 sslContext.init(km, tm, random); 143 144 return sslContext; 145 } 146 147 /** 148 * Sets the key manager which the SSL context should use. By default, no key 149 * manager is specified indicating that no certificates will be used. 150 * 151 * @param keyManager 152 * The key manager which the SSL context should use, which may be 153 * {@code null} indicating that no certificates will be used. 154 * @return This SSL context builder. 155 */ 156 public SSLContextBuilder setKeyManager(final KeyManager keyManager) { 157 this.keyManager = keyManager; 158 return this; 159 } 160 161 /** 162 * Sets the protocol which the SSL context should use. By default, TLSv1 163 * will be used. 164 * 165 * @param protocol 166 * The protocol which the SSL context should use, which may be 167 * {@code null} indicating that TLSv1 will be used. 168 * @return This SSL context builder. 169 */ 170 public SSLContextBuilder setProtocol(final String protocol) { 171 this.protocol = protocol; 172 return this; 173 } 174 175 /** 176 * Sets the provider which the SSL context should use. By default, the 177 * default provider associated with this JVM will be used. 178 * 179 * @param provider 180 * The provider which the SSL context should use, which may be 181 * {@code null} indicating that the default provider associated 182 * with this JVM will be used. 183 * @return This SSL context builder. 184 */ 185 public SSLContextBuilder setProvider(final Provider provider) { 186 this.provider = provider; 187 this.providerName = null; 188 return this; 189 } 190 191 /** 192 * Sets the provider which the SSL context should use. By default, the 193 * default provider associated with this JVM will be used. 194 * 195 * @param providerName 196 * The name of the provider which the SSL context should use, 197 * which may be {@code null} indicating that the default provider 198 * associated with this JVM will be used. 199 * @return This SSL context builder. 200 */ 201 public SSLContextBuilder setProvider(final String providerName) { 202 this.provider = null; 203 this.providerName = providerName; 204 return this; 205 } 206 207 /** 208 * Sets the secure random number generator which the SSL context should use. 209 * By default, the default secure random number generator associated with 210 * this JVM will be used. 211 * 212 * @param random 213 * The secure random number generator which the SSL context 214 * should use, which may be {@code null} indicating that the 215 * default secure random number generator associated with this 216 * JVM will be used. 217 * @return This SSL context builder. 218 */ 219 public SSLContextBuilder setSecureRandom(final SecureRandom random) { 220 this.random = random; 221 return this; 222 } 223 224 /** 225 * Sets the trust manager which the SSL context should use. By default, no 226 * trust manager is specified indicating that only certificates signed by 227 * the authorities associated with this JVM will be accepted. 228 * 229 * @param trustManager 230 * The trust manager which the SSL context should use, which may 231 * be {@code null} indicating that only certificates signed by 232 * the authorities associated with this JVM will be accepted. 233 * @return This SSL context builder. 234 */ 235 public SSLContextBuilder setTrustManager(final TrustManager trustManager) { 236 this.trustManager = trustManager; 237 return this; 238 } 239}