692 lines · 23.6 KB · Java
RawDownload
/* * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * NOTE:  this file was copied from javax.net.ssl.SSLSecurity, * but was heavily modified to allow com.sun.* users to * access providers written using the javax.sun.* APIs. */ package com.sun.net.ssl; import java.util.*;import java.io.*;import java.security.*;import java.security.Provider.Service;import java.net.Socket; import sun.security.jca.*; /** * This class instantiates implementations of JSSE engine classes from * providers registered with the java.security.Security object. * * @author Jan Luehe * @author Jeff Nisewanger * @author Brad Wetmore */ final class SSLSecurity {     /*     * Don't let anyone instantiate this.     */    private SSLSecurity() {    }      // ProviderList.getService() is not accessible now, implement our own loop    private static Service getService(String type, String alg) {        ProviderList list = Providers.getProviderList();        for (Provider p : list.providers()) {            Service s = p.getService(type, alg);            if (s != null) {                return s;            }        }        return null;    }     /**     * The body of the driver for the getImpl method.     */    private static Object[] getImpl1(String algName, String engineType,            Service service) throws NoSuchAlgorithmException    {        Provider provider = service.getProvider();        String className = service.getClassName();        Class implClass;        try {            ClassLoader cl = provider.getClass().getClassLoader();            if (cl == null) {                // system class                implClass = Class.forName(className);            } else {                implClass = cl.loadClass(className);            }        } catch (ClassNotFoundException e) {            throw new NoSuchAlgorithmException("Class " + className +                                                " configured for " +                                                engineType +                                                " not found: " +                                                e.getMessage());        } catch (SecurityException e) {            throw new NoSuchAlgorithmException("Class " + className +                                                " configured for " +                                                engineType +                                                " cannot be accessed: " +                                                e.getMessage());        }         /*         * JSSE 1.0, 1.0.1, and 1.0.2 used the com.sun.net.ssl API as the         * API was being developed.  As JSSE was folded into the main         * release, it was decided to promote the com.sun.net.ssl API to         * be javax.net.ssl.  It is desired to keep binary compatibility         * with vendors of JSSE implementation written using the         * com.sun.net.sll API, so we do this magic to handle everything.         *         * API used     Implementation used     Supported?         * ========     ===================     ==========         * com.sun      javax                   Yes         * com.sun      com.sun                 Yes         * javax        javax                   Yes         * javax        com.sun                 Not Currently         *         * Make sure the implementation class is a subclass of the         * corresponding engine class.         *         * In wrapping these classes, there's no way to know how to         * wrap all possible classes that extend the TrustManager/KeyManager.         * We only wrap the x509 variants.         */         try {   // catch instantiation errors             /*             * (The following Class.forName()s should alway work, because             * this class and all the SPI classes in javax.crypto are             * loaded by the same class loader.)  That is, unless they             * give us a SPI class that doesn't exist, say SSLFoo,             * or someone has removed classes from the jsse.jar file.             */             Class typeClassJavax;            Class typeClassCom;            Object obj = null;             /*             * Odds are more likely that we have a javax variant, try this             * first.             */            if (((typeClassJavax = Class.forName("javax.net.ssl." +                    engineType + "Spi")) != null) &&                    (checkSuperclass(implClass, typeClassJavax))) {                 if (engineType.equals("SSLContext")) {                    obj = new SSLContextSpiWrapper(algName, provider);                } else if (engineType.equals("TrustManagerFactory")) {                    obj = new TrustManagerFactorySpiWrapper(algName, provider);                } else if (engineType.equals("KeyManagerFactory")) {                    obj = new KeyManagerFactorySpiWrapper(algName, provider);                } else {                    /*                     * We should throw an error if we get                     * something totally unexpected.  Don't ever                     * expect to see this one...                     */                    throw new IllegalStateException(                        "Class " + implClass.getName() +                        " unknown engineType wrapper:" + engineType);                }             } else if (((typeClassCom = Class.forName("com.sun.net.ssl." +                        engineType + "Spi")) != null) &&                        (checkSuperclass(implClass, typeClassCom))) {                obj = service.newInstance(null);            }             if (obj != null) {                return new Object[] { obj, provider };            } else {                throw new NoSuchAlgorithmException(                    "Couldn't locate correct object or wrapper: " +                    engineType + " " + algName);            }         } catch (ClassNotFoundException e) {            IllegalStateException exc = new IllegalStateException(                "Engine Class Not Found for " + engineType);            exc.initCause(e);            throw exc;        }    }     /**     * Returns an array of objects: the first object in the array is     * an instance of an implementation of the requested algorithm     * and type, and the second object in the array identifies the provider     * of that implementation.     * The <code>provName</code> argument can be null, in which case all     * configured providers will be searched in order of preference.     */    static Object[] getImpl(String algName, String engineType, String provName)        throws NoSuchAlgorithmException, NoSuchProviderException    {        Service service;        if (provName != null) {            ProviderList list = Providers.getProviderList();            Provider prov = list.getProvider(provName);            if (prov == null) {                throw new NoSuchProviderException("No such provider: " +                                                  provName);            }            service = prov.getService(engineType, algName);        } else {            service = getService(engineType, algName);        }        if (service == null) {            throw new NoSuchAlgorithmException("Algorithm " + algName                                               + " not available");        }        return getImpl1(algName, engineType, service);    }      /**     * Returns an array of objects: the first object in the array is     * an instance of an implementation of the requested algorithm     * and type, and the second object in the array identifies the provider     * of that implementation.     * The <code>prov</code> argument can be null, in which case all     * configured providers will be searched in order of preference.     */    static Object[] getImpl(String algName, String engineType, Provider prov)        throws NoSuchAlgorithmException    {        Service service = prov.getService(engineType, algName);        if (service == null) {            throw new NoSuchAlgorithmException("No such algorithm: " +                                               algName);        }        return getImpl1(algName, engineType, service);    }     /*     * Checks whether one class is the superclass of another     */    private static boolean checkSuperclass(Class subclass, Class superclass) {        if ((subclass == null) || (superclass == null))                return false;         while (!subclass.equals(superclass)) {            subclass = subclass.getSuperclass();            if (subclass == null) {                return false;            }        }        return true;    }     /*     * Return at most the first "resize" elements of an array.     *     * Didn't want to use java.util.Arrays, as PJava may not have it.     */    static Object[] truncateArray(Object[] oldArray, Object[] newArray) {         for (int i = 0; i < newArray.length; i++) {            newArray[i] = oldArray[i];        }         return newArray;    } }  /* * ================================================================= * The remainder of this file is for the wrapper and wrapper-support * classes.  When SSLSecurity finds something which extends the * javax.net.ssl.*Spi, we need to go grab a real instance of the * thing that the Spi supports, and wrap into a com.sun.net.ssl.*Spi * object.  This also mean that anything going down into the SPI * needs to be wrapped, as well as anything coming back up. */ final class SSLContextSpiWrapper extends SSLContextSpi {     private javax.net.ssl.SSLContext theSSLContext;     SSLContextSpiWrapper(String algName, Provider prov) throws            NoSuchAlgorithmException {        theSSLContext = javax.net.ssl.SSLContext.getInstance(algName, prov);    }     protected void engineInit(KeyManager[] kma, TrustManager[] tma,            SecureRandom sr) throws KeyManagementException {         // Keep track of the actual number of array elements copied        int dst;        int src;        javax.net.ssl.KeyManager[] kmaw;        javax.net.ssl.TrustManager[] tmaw;         // Convert com.sun.net.ssl.kma to a javax.net.ssl.kma        // wrapper if need be.        if (kma != null) {            kmaw = new javax.net.ssl.KeyManager[kma.length];            for (src = 0, dst = 0; src < kma.length; ) {                /*                 * These key managers may implement both javax                 * and com.sun interfaces, so if they do                 * javax, there's no need to wrap them.                 */                if (!(kma[src] instanceof javax.net.ssl.KeyManager)) {                    /*                     * Do we know how to convert them?  If not, oh well...                     * We'll have to drop them on the floor in this                     * case, cause we don't know how to handle them.                     * This will be pretty rare, but put here for                     * completeness.                     */                    if (kma[src] instanceof X509KeyManager) {                        kmaw[dst] = (javax.net.ssl.KeyManager)                            new X509KeyManagerJavaxWrapper(                            (X509KeyManager)kma[src]);                        dst++;                    }                } else {                    // We can convert directly, since they implement.                    kmaw[dst] = (javax.net.ssl.KeyManager)kma[src];                    dst++;                }                src++;            }             /*             * If dst != src, there were more items in the original array             * than in the new array.  Compress the new elements to avoid             * any problems down the road.             */            if (dst != src) {                    kmaw = (javax.net.ssl.KeyManager [])                        SSLSecurity.truncateArray(kmaw,                            new javax.net.ssl.KeyManager [dst]);            }        } else {            kmaw = null;        }         // Now do the same thing with the TrustManagers.        if (tma != null) {            tmaw = new javax.net.ssl.TrustManager[tma.length];             for (src = 0, dst = 0; src < tma.length; ) {                /*                 * These key managers may implement both...see above...                 */                if (!(tma[src] instanceof javax.net.ssl.TrustManager)) {                    // Do we know how to convert them?                    if (tma[src] instanceof X509TrustManager) {                        tmaw[dst] = (javax.net.ssl.TrustManager)                            new X509TrustManagerJavaxWrapper(                            (X509TrustManager)tma[src]);                        dst++;                    }                } else {                    tmaw[dst] = (javax.net.ssl.TrustManager)tma[src];                    dst++;                }                src++;            }             if (dst != src) {                tmaw = (javax.net.ssl.TrustManager [])                    SSLSecurity.truncateArray(tmaw,                        new javax.net.ssl.TrustManager [dst]);            }        } else {            tmaw = null;        }         theSSLContext.init(kmaw, tmaw, sr);    }     protected javax.net.ssl.SSLSocketFactory            engineGetSocketFactory() {        return theSSLContext.getSocketFactory();    }     protected javax.net.ssl.SSLServerSocketFactory            engineGetServerSocketFactory() {        return theSSLContext.getServerSocketFactory();    } } final class TrustManagerFactorySpiWrapper extends TrustManagerFactorySpi {     private javax.net.ssl.TrustManagerFactory theTrustManagerFactory;     TrustManagerFactorySpiWrapper(String algName, Provider prov) throws            NoSuchAlgorithmException {        theTrustManagerFactory =            javax.net.ssl.TrustManagerFactory.getInstance(algName, prov);    }     protected void engineInit(KeyStore ks) throws KeyStoreException {        theTrustManagerFactory.init(ks);    }     protected TrustManager[] engineGetTrustManagers() {         int dst;        int src;         javax.net.ssl.TrustManager[] tma =            theTrustManagerFactory.getTrustManagers();         TrustManager[] tmaw = new TrustManager[tma.length];         for (src = 0, dst = 0; src < tma.length; ) {            if (!(tma[src] instanceof com.sun.net.ssl.TrustManager)) {                // We only know how to wrap X509TrustManagers, as                // TrustManagers don't have any methods to wrap.                if (tma[src] instanceof javax.net.ssl.X509TrustManager) {                    tmaw[dst] = (TrustManager)                        new X509TrustManagerComSunWrapper(                        (javax.net.ssl.X509TrustManager)tma[src]);                    dst++;                }            } else {                tmaw[dst] = (TrustManager)tma[src];                dst++;            }            src++;        }         if (dst != src) {            tmaw = (TrustManager [])                SSLSecurity.truncateArray(tmaw, new TrustManager [dst]);        }         return tmaw;    } } final class KeyManagerFactorySpiWrapper extends KeyManagerFactorySpi {     private javax.net.ssl.KeyManagerFactory theKeyManagerFactory;     KeyManagerFactorySpiWrapper(String algName, Provider prov) throws            NoSuchAlgorithmException {        theKeyManagerFactory =            javax.net.ssl.KeyManagerFactory.getInstance(algName, prov);    }     protected void engineInit(KeyStore ks, char[] password)            throws KeyStoreException, NoSuchAlgorithmException,            UnrecoverableKeyException {        theKeyManagerFactory.init(ks, password);    }     protected KeyManager[] engineGetKeyManagers() {         int dst;        int src;         javax.net.ssl.KeyManager[] kma =            theKeyManagerFactory.getKeyManagers();         KeyManager[] kmaw = new KeyManager[kma.length];         for (src = 0, dst = 0; src < kma.length; ) {            if (!(kma[src] instanceof com.sun.net.ssl.KeyManager)) {                // We only know how to wrap X509KeyManagers, as                // KeyManagers don't have any methods to wrap.                if (kma[src] instanceof javax.net.ssl.X509KeyManager) {                    kmaw[dst] = (KeyManager)                        new X509KeyManagerComSunWrapper(                        (javax.net.ssl.X509KeyManager)kma[src]);                    dst++;                }            } else {                kmaw[dst] = (KeyManager)kma[src];                dst++;            }            src++;        }         if (dst != src) {            kmaw = (KeyManager [])                SSLSecurity.truncateArray(kmaw, new KeyManager [dst]);        }         return kmaw;    } } // ================================= final class X509KeyManagerJavaxWrapper implements        javax.net.ssl.X509KeyManager {     private X509KeyManager theX509KeyManager;

Lines 1–500 of 692.