Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/naming/ldap/StartTlsRequest.java
38918 views
/*1* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.naming.ldap;2627import java.util.Iterator;28import java.security.AccessController;29import java.security.PrivilegedAction;30import javax.naming.ConfigurationException;31import javax.naming.NamingException;32import com.sun.naming.internal.VersionHelper;33import java.util.ServiceLoader;34import java.util.ServiceConfigurationError;3536/**37* This class implements the LDAPv3 Extended Request for StartTLS as38* defined in39* <a href="http://www.ietf.org/rfc/rfc2830.txt">Lightweight Directory40* Access Protocol (v3): Extension for Transport Layer Security</a>41*42* The object identifier for StartTLS is 1.3.6.1.4.1.1466.2003743* and no extended request value is defined.44*<p>45* <tt>StartTlsRequest</tt>/<tt>StartTlsResponse</tt> are used to establish46* a TLS connection over the existing LDAP connection associated with47* the JNDI context on which <tt>extendedOperation()</tt> is invoked.48* Typically, a JNDI program uses these classes as follows.49* <blockquote><pre>50* import javax.naming.ldap.*;51*52* // Open an LDAP association53* LdapContext ctx = new InitialLdapContext();54*55* // Perform a StartTLS extended operation56* StartTlsResponse tls =57* (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());58*59* // Open a TLS connection (over the existing LDAP association) and get details60* // of the negotiated TLS session: cipher suite, peer certificate, etc.61* SSLSession session = tls.negotiate();62*63* // ... use ctx to perform protected LDAP operations64*65* // Close the TLS connection (revert back to the underlying LDAP association)66* tls.close();67*68* // ... use ctx to perform unprotected LDAP operations69*70* // Close the LDAP association71* ctx.close;72* </pre></blockquote>73*74* @since 1.475* @see StartTlsResponse76* @author Vincent Ryan77*/78public class StartTlsRequest implements ExtendedRequest {7980// Constant8182/**83* The StartTLS extended request's assigned object identifier84* is 1.3.6.1.4.1.1466.20037.85*/86public static final String OID = "1.3.6.1.4.1.1466.20037";878889// Constructors9091/**92* Constructs a StartTLS extended request.93*/94public StartTlsRequest() {95}969798// ExtendedRequest methods99100/**101* Retrieves the StartTLS request's object identifier string.102*103* @return The object identifier string, "1.3.6.1.4.1.1466.20037".104*/105public String getID() {106return OID;107}108109/**110* Retrieves the StartTLS request's ASN.1 BER encoded value.111* Since the request has no defined value, null is always112* returned.113*114* @return The null value.115*/116public byte[] getEncodedValue() {117return null;118}119120/**121* Creates an extended response object that corresponds to the122* LDAP StartTLS extended request.123* <p>124* The result must be a concrete subclass of StartTlsResponse125* and must have a public zero-argument constructor.126* <p>127* This method locates the implementation class by locating128* configuration files that have the name:129* <blockquote><tt>130* META-INF/services/javax.naming.ldap.StartTlsResponse131* </tt></blockquote>132* The configuration files and their corresponding implementation classes must133* be accessible to the calling thread's context class loader.134* <p>135* Each configuration file should contain a list of fully-qualified class136* names, one per line. Space and tab characters surrounding each name, as137* well as blank lines, are ignored. The comment character is <tt>'#'</tt>138* (<tt>0x23</tt>); on each line all characters following the first comment139* character are ignored. The file must be encoded in UTF-8.140* <p>141* This method will return an instance of the first implementation142* class that it is able to load and instantiate successfully from143* the list of class names collected from the configuration files.144* This method uses the calling thread's context classloader to find the145* configuration files and to load the implementation class.146* <p>147* If no class can be found in this way, this method will use148* an implementation-specific way to locate an implementation.149* If none is found, a NamingException is thrown.150*151* @param id The object identifier of the extended response.152* Its value must be "1.3.6.1.4.1.1466.20037" or null.153* Both values are equivalent.154* @param berValue The possibly null ASN.1 BER encoded value of the155* extended response. This is the raw BER bytes156* including the tag and length of the response value.157* It does not include the response OID.158* Its value is ignored because a Start TLS response159* is not expected to contain any response value.160* @param offset The starting position in berValue of the bytes to use.161* Its value is ignored because a Start TLS response162* is not expected to contain any response value.163* @param length The number of bytes in berValue to use.164* Its value is ignored because a Start TLS response165* is not expected to contain any response value.166* @return The StartTLS extended response object.167* @exception NamingException If a naming exception was encountered168* while creating the StartTLS extended response object.169*/170public ExtendedResponse createExtendedResponse(String id, byte[] berValue,171int offset, int length) throws NamingException {172173// Confirm that the object identifier is correct174if ((id != null) && (!id.equals(OID))) {175throw new ConfigurationException(176"Start TLS received the following response instead of " +177OID + ": " + id);178}179180StartTlsResponse resp = null;181182ServiceLoader<StartTlsResponse> sl = ServiceLoader.load(183StartTlsResponse.class, getContextClassLoader());184Iterator<StartTlsResponse> iter = sl.iterator();185186while (resp == null && privilegedHasNext(iter)) {187resp = iter.next();188}189if (resp != null) {190return resp;191}192try {193VersionHelper helper = VersionHelper.getVersionHelper();194Class<?> clas = helper.loadClass(195"com.sun.jndi.ldap.ext.StartTlsResponseImpl");196197resp = (StartTlsResponse) clas.newInstance();198199} catch (IllegalAccessException e) {200throw wrapException(e);201202} catch (InstantiationException e) {203throw wrapException(e);204205} catch (ClassNotFoundException e) {206throw wrapException(e);207}208209return resp;210}211212/*213* Wrap an exception, thrown while attempting to load the StartTlsResponse214* class, in a configuration exception.215*/216private ConfigurationException wrapException(Exception e) {217ConfigurationException ce = new ConfigurationException(218"Cannot load implementation of javax.naming.ldap.StartTlsResponse");219220ce.setRootCause(e);221return ce;222}223224/*225* Acquire the class loader associated with this thread.226*/227private final ClassLoader getContextClassLoader() {228return AccessController.doPrivileged(229new PrivilegedAction<ClassLoader>() {230public ClassLoader run() {231return Thread.currentThread().getContextClassLoader();232}233}234);235}236237private final static boolean privilegedHasNext(final Iterator<StartTlsResponse> iter) {238Boolean answer = AccessController.doPrivileged(239new PrivilegedAction<Boolean>() {240public Boolean run() {241return Boolean.valueOf(iter.hasNext());242}243});244return answer.booleanValue();245}246247private static final long serialVersionUID = 4441679576360753397L;248}249250251