|
From: <ls...@us...> - 2007-06-23 04:52:59
|
Revision: 3287
http://jnode.svn.sourceforge.net/jnode/?rev=3287&view=rev
Author: lsantha
Date: 2007-06-22 21:52:58 -0700 (Fri, 22 Jun 2007)
Log Message:
-----------
Openjdk integration.
Added Paths:
-----------
trunk/core/src/openjdk/java/java/security/AlgorithmParameters.java
trunk/core/src/openjdk/java/java/security/KeyRep.java
trunk/core/src/openjdk/java/java/security/Provider.java
trunk/core/src/openjdk/java/java/security/cert/
trunk/core/src/openjdk/java/java/security/cert/CRL.java
trunk/core/src/openjdk/java/java/security/cert/CRLException.java
trunk/core/src/openjdk/java/java/security/cert/CRLSelector.java
trunk/core/src/openjdk/java/java/security/cert/CertPath.java
trunk/core/src/openjdk/java/java/security/cert/CertPathBuilder.java
trunk/core/src/openjdk/java/java/security/cert/CertPathBuilderException.java
trunk/core/src/openjdk/java/java/security/cert/CertPathBuilderResult.java
trunk/core/src/openjdk/java/java/security/cert/CertPathBuilderSpi.java
trunk/core/src/openjdk/java/java/security/cert/CertPathHelperImpl.java
trunk/core/src/openjdk/java/java/security/cert/CertPathParameters.java
trunk/core/src/openjdk/java/java/security/cert/CertPathValidator.java
trunk/core/src/openjdk/java/java/security/cert/CertPathValidatorException.java
trunk/core/src/openjdk/java/java/security/cert/CertPathValidatorResult.java
trunk/core/src/openjdk/java/java/security/cert/CertPathValidatorSpi.java
trunk/core/src/openjdk/java/java/security/cert/CertSelector.java
trunk/core/src/openjdk/java/java/security/cert/CertStore.java
trunk/core/src/openjdk/java/java/security/cert/CertStoreException.java
trunk/core/src/openjdk/java/java/security/cert/CertStoreParameters.java
trunk/core/src/openjdk/java/java/security/cert/CertStoreSpi.java
trunk/core/src/openjdk/java/java/security/cert/Certificate.java
trunk/core/src/openjdk/java/java/security/cert/CertificateEncodingException.java
trunk/core/src/openjdk/java/java/security/cert/CertificateException.java
trunk/core/src/openjdk/java/java/security/cert/CertificateExpiredException.java
trunk/core/src/openjdk/java/java/security/cert/CertificateFactory.java
trunk/core/src/openjdk/java/java/security/cert/CertificateFactorySpi.java
trunk/core/src/openjdk/java/java/security/cert/CertificateNotYetValidException.java
trunk/core/src/openjdk/java/java/security/cert/CertificateParsingException.java
trunk/core/src/openjdk/java/java/security/cert/CollectionCertStoreParameters.java
trunk/core/src/openjdk/java/java/security/cert/LDAPCertStoreParameters.java
trunk/core/src/openjdk/java/java/security/cert/PKIXBuilderParameters.java
trunk/core/src/openjdk/java/java/security/cert/PKIXCertPathBuilderResult.java
trunk/core/src/openjdk/java/java/security/cert/PKIXCertPathChecker.java
trunk/core/src/openjdk/java/java/security/cert/PKIXCertPathValidatorResult.java
trunk/core/src/openjdk/java/java/security/cert/PKIXParameters.java
trunk/core/src/openjdk/java/java/security/cert/PolicyNode.java
trunk/core/src/openjdk/java/java/security/cert/PolicyQualifierInfo.java
trunk/core/src/openjdk/java/java/security/cert/TrustAnchor.java
trunk/core/src/openjdk/java/java/security/cert/X509CRL.java
trunk/core/src/openjdk/java/java/security/cert/X509CRLEntry.java
trunk/core/src/openjdk/java/java/security/cert/X509CRLSelector.java
trunk/core/src/openjdk/java/java/security/cert/X509CertSelector.java
trunk/core/src/openjdk/java/java/security/cert/X509Certificate.java
trunk/core/src/openjdk/java/java/security/cert/X509Extension.java
trunk/core/src/openjdk/java/java/security/cert/package.html
trunk/core/src/openjdk/java/java/security/interfaces/
trunk/core/src/openjdk/java/java/security/interfaces/ECKey.java
trunk/core/src/openjdk/java/java/security/interfaces/ECPrivateKey.java
trunk/core/src/openjdk/java/java/security/interfaces/ECPublicKey.java
trunk/core/src/openjdk/java/java/security/spec/
trunk/core/src/openjdk/java/java/security/spec/ECField.java
trunk/core/src/openjdk/java/java/security/spec/ECFieldF2m.java
trunk/core/src/openjdk/java/java/security/spec/ECFieldFp.java
trunk/core/src/openjdk/java/java/security/spec/ECGenParameterSpec.java
trunk/core/src/openjdk/java/java/security/spec/ECParameterSpec.java
trunk/core/src/openjdk/java/java/security/spec/ECPoint.java
trunk/core/src/openjdk/java/java/security/spec/ECPrivateKeySpec.java
trunk/core/src/openjdk/java/java/security/spec/ECPublicKeySpec.java
trunk/core/src/openjdk/java/java/security/spec/EllipticCurve.java
Added: trunk/core/src/openjdk/java/java/security/AlgorithmParameters.java
===================================================================
--- trunk/core/src/openjdk/java/java/security/AlgorithmParameters.java (rev 0)
+++ trunk/core/src/openjdk/java/java/security/AlgorithmParameters.java 2007-06-23 04:52:58 UTC (rev 3287)
@@ -0,0 +1,383 @@
+/*
+ * Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.security;
+
+import java.io.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+/**
+ * This class is used as an opaque representation of cryptographic parameters.
+ *
+ * <p>An <code>AlgorithmParameters</code> object for managing the parameters
+ * for a particular algorithm can be obtained by
+ * calling one of the <code>getInstance</code> factory methods
+ * (static methods that return instances of a given class).
+ *
+ * <p>Once an <code>AlgorithmParameters</code> object is obtained, it must be
+ * initialized via a call to <code>init</code>, using an appropriate parameter
+ * specification or parameter encoding.
+ *
+ * <p>A transparent parameter specification is obtained from an
+ * <code>AlgorithmParameters</code> object via a call to
+ * <code>getParameterSpec</code>, and a byte encoding of the parameters is
+ * obtained via a call to <code>getEncoded</code>.
+ *
+ * @author Jan Luehe
+ *
+ * @version 1.33, 05/05/07
+ *
+ * @see java.security.spec.AlgorithmParameterSpec
+ * @see java.security.spec.DSAParameterSpec
+ * @see KeyPairGenerator
+ *
+ * @since 1.2
+ */
+
+public class AlgorithmParameters {
+
+ // The provider
+ private Provider provider;
+
+ // The provider implementation (delegate)
+ private AlgorithmParametersSpi paramSpi;
+
+ // The algorithm
+ private String algorithm;
+
+ // Has this object been initialized?
+ private boolean initialized = false;
+
+ /**
+ * Creates an AlgorithmParameters object.
+ *
+ * @param paramSpi the delegate
+ * @param provider the provider
+ * @param algorithm the algorithm
+ */
+ protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
+ Provider provider, String algorithm)
+ {
+ this.paramSpi = paramSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
+ }
+
+ /**
+ * Returns the name of the algorithm associated with this parameter object.
+ *
+ * @return the algorithm name.
+ */
+ public final String getAlgorithm() {
+ return this.algorithm;
+ }
+
+ /**
+ * Returns a parameter object for the specified algorithm.
+ *
+ * <p> This method traverses the list of registered security Providers,
+ * starting with the most preferred Provider.
+ * A new AlgorithmParameters object encapsulating the
+ * AlgorithmParametersSpi implementation from the first
+ * Provider that supports the specified algorithm is returned.
+ *
+ * <p> Note that the list of registered providers may be retrieved via
+ * the {@link Security#getProviders() Security.getProviders()} method.
+ *
+ * <p> The returned parameter object must be initialized via a call to
+ * <code>init</code>, using an appropriate parameter specification or
+ * parameter encoding.
+ *
+ * @param algorithm the name of the algorithm requested.
+ * See Appendix A in the <a href=
+ * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * Java Cryptography Architecture API Specification & Reference </a>
+ * for information about standard algorithm names.
+ *
+ * @return the new parameter object.
+ *
+ * @exception NoSuchAlgorithmException if no Provider supports an
+ * AlgorithmParametersSpi implementation for the
+ * specified algorithm.
+ *
+ * @see Provider
+ */
+ public static AlgorithmParameters getInstance(String algorithm)
+ throws NoSuchAlgorithmException {
+ try {
+ Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
+ (String)null);
+ return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
+ (Provider)objs[1],
+ algorithm);
+ } catch(NoSuchProviderException e) {
+ throw new NoSuchAlgorithmException(algorithm + " not found");
+ }
+ }
+
+ /**
+ * Returns a parameter object for the specified algorithm.
+ *
+ * <p> A new AlgorithmParameters object encapsulating the
+ * AlgorithmParametersSpi implementation from the specified provider
+ * is returned. The specified provider must be registered
+ * in the security provider list.
+ *
+ * <p> Note that the list of registered providers may be retrieved via
+ * the {@link Security#getProviders() Security.getProviders()} method.
+ *
+ * <p>The returned parameter object must be initialized via a call to
+ * <code>init</code>, using an appropriate parameter specification or
+ * parameter encoding.
+ *
+ * @param algorithm the name of the algorithm requested.
+ * See Appendix A in the <a href=
+ * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * Java Cryptography Architecture API Specification & Reference </a>
+ * for information about standard algorithm names.
+ *
+ * @param provider the name of the provider.
+ *
+ * @return the new parameter object.
+ *
+ * @exception NoSuchAlgorithmException if an AlgorithmParametersSpi
+ * implementation for the specified algorithm is not
+ * available from the specified provider.
+ *
+ * @exception NoSuchProviderException if the specified provider is not
+ * registered in the security provider list.
+ *
+ * @exception IllegalArgumentException if the provider name is null
+ * or empty.
+ *
+ * @see Provider
+ */
+ public static AlgorithmParameters getInstance(String algorithm,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (provider == null || provider.length() == 0)
+ throw new IllegalArgumentException("missing provider");
+ Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
+ provider);
+ return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
+ (Provider)objs[1],
+ algorithm);
+ }
+
+ /**
+ * Returns a parameter object for the specified algorithm.
+ *
+ * <p> A new AlgorithmParameters object encapsulating the
+ * AlgorithmParametersSpi implementation from the specified Provider
+ * object is returned. Note that the specified Provider object
+ * does not have to be registered in the provider list.
+ *
+ * <p>The returned parameter object must be initialized via a call to
+ * <code>init</code>, using an appropriate parameter specification or
+ * parameter encoding.
+ *
+ * @param algorithm the name of the algorithm requested.
+ * See Appendix A in the <a href=
+ * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * Java Cryptography Architecture API Specification & Reference </a>
+ * for information about standard algorithm names.
+ *
+ * @param provider the name of the provider.
+ *
+ * @return the new parameter object.
+ *
+ * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
+ * implementation for the specified algorithm is not available
+ * from the specified Provider object.
+ *
+ * @exception IllegalArgumentException if the provider is null.
+ *
+ * @see Provider
+ *
+ * @since 1.4
+ */
+ public static AlgorithmParameters getInstance(String algorithm,
+ Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ if (provider == null)
+ throw new IllegalArgumentException("missing provider");
+ Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
+ provider);
+ return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
+ (Provider)objs[1],
+ algorithm);
+ }
+
+ /**
+ * Returns the provider of this parameter object.
+ *
+ * @return the provider of this parameter object
+ */
+ public final Provider getProvider() {
+ return this.provider;
+ }
+
+ /**
+ * Initializes this parameter object using the parameters
+ * specified in <code>paramSpec</code>.
+ *
+ * @param paramSpec the parameter specification.
+ *
+ * @exception InvalidParameterSpecException if the given parameter
+ * specification is inappropriate for the initialization of this parameter
+ * object, or if this parameter object has already been initialized.
+ */
+ public final void init(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (this.initialized)
+ throw new InvalidParameterSpecException("already initialized");
+ paramSpi.engineInit(paramSpec);
+ this.initialized = true;
+ }
+
+ /**
+ * Imports the specified parameters and decodes them according to the
+ * primary decoding format for parameters. The primary decoding
+ * format for parameters is ASN.1, if an ASN.1 specification for this type
+ * of parameters exists.
+ *
+ * @param params the encoded parameters.
+ *
+ * @exception IOException on decoding errors, or if this parameter object
+ * has already been initialized.
+ */
+ public final void init(byte[] params) throws IOException {
+ if (this.initialized)
+ throw new IOException("already initialized");
+ paramSpi.engineInit(params);
+ this.initialized = true;
+ }
+
+ /**
+ * Imports the parameters from <code>params</code> and decodes them
+ * according to the specified decoding scheme.
+ * If <code>format</code> is null, the
+ * primary decoding format for parameters is used. The primary decoding
+ * format is ASN.1, if an ASN.1 specification for these parameters
+ * exists.
+ *
+ * @param params the encoded parameters.
+ *
+ * @param format the name of the decoding scheme.
+ *
+ * @exception IOException on decoding errors, or if this parameter object
+ * has already been initialized.
+ */
+ public final void init(byte[] params, String format) throws IOException {
+ if (this.initialized)
+ throw new IOException("already initialized");
+ paramSpi.engineInit(params, format);
+ this.initialized = true;
+ }
+
+ /**
+ * Returns a (transparent) specification of this parameter object.
+ * <code>paramSpec</code> identifies the specification class in which
+ * the parameters should be returned. It could, for example, be
+ * <code>DSAParameterSpec.class</code>, to indicate that the
+ * parameters should be returned in an instance of the
+ * <code>DSAParameterSpec</code> class.
+ *
+ * @param paramSpec the specification class in which
+ * the parameters should be returned.
+ *
+ * @return the parameter specification.
+ *
+ * @exception InvalidParameterSpecException if the requested parameter
+ * specification is inappropriate for this parameter object, or if this
+ * parameter object has not been initialized.
+ */
+ public final <T extends AlgorithmParameterSpec>
+ T getParameterSpec(Class<T> paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (this.initialized == false) {
+ throw new InvalidParameterSpecException("not initialized");
+ }
+ return paramSpi.engineGetParameterSpec(paramSpec);
+ }
+
+ /**
+ * Returns the parameters in their primary encoding format.
+ * The primary encoding format for parameters is ASN.1, if an ASN.1
+ * specification for this type of parameters exists.
+ *
+ * @return the parameters encoded using their primary encoding format.
+ *
+ * @exception IOException on encoding errors, or if this parameter object
+ * has not been initialized.
+ */
+ public final byte[] getEncoded() throws IOException
+ {
+ if (this.initialized == false) {
+ throw new IOException("not initialized");
+ }
+ return paramSpi.engineGetEncoded();
+ }
+
+ /**
+ * Returns the parameters encoded in the specified scheme.
+ * If <code>format</code> is null, the
+ * primary encoding format for parameters is used. The primary encoding
+ * format is ASN.1, if an ASN.1 specification for these parameters
+ * exists.
+ *
+ * @param format the name of the encoding format.
+ *
+ * @return the parameters encoded using the specified encoding scheme.
+ *
+ * @exception IOException on encoding errors, or if this parameter object
+ * has not been initialized.
+ */
+ public final byte[] getEncoded(String format) throws IOException
+ {
+ if (this.initialized == false) {
+ throw new IOException("not initialized");
+ }
+ return paramSpi.engineGetEncoded(format);
+ }
+
+ /**
+ * Returns a formatted string describing the parameters.
+ *
+ * @return a formatted string describing the parameters, or null if this
+ * parameter object has not been initialized.
+ */
+ public final String toString() {
+ if (this.initialized == false) {
+ return null;
+ }
+ return paramSpi.engineToString();
+ }
+}
Added: trunk/core/src/openjdk/java/java/security/KeyRep.java
===================================================================
--- trunk/core/src/openjdk/java/java/security/KeyRep.java (rev 0)
+++ trunk/core/src/openjdk/java/java/security/KeyRep.java 2007-06-23 04:52:58 UTC (rev 3287)
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.security;
+
+import java.io.*;
+
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.security.spec.InvalidKeySpecException;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Standardized representation for serialized Key objects.
+ *
+ * <p>
+ *
+ * Note that a serialized Key may contain sensitive information
+ * which should not be exposed in untrusted environments. See the
+ * <a href="../../../platform/serialization/spec/security.html">
+ * Security Appendix</a>
+ * of the Serialization Specification for more information.
+ *
+ * @see Key
+ * @see KeyFactory
+ * @see javax.crypto.spec.SecretKeySpec
+ * @see java.security.spec.X509EncodedKeySpec
+ * @see java.security.spec.PKCS8EncodedKeySpec
+ *
+ * @version 1.16, 07/05/05
+ * @since 1.5
+ */
+
+public class KeyRep implements Serializable {
+
+ private static final long serialVersionUID = -4757683898830641853L;
+
+ /**
+ * Key type.
+ *
+ * @since 1.5
+ */
+ public static enum Type {
+
+ /** Type for secret keys. */
+ SECRET,
+
+ /** Type for public keys. */
+ PUBLIC,
+
+ /** Type for private keys. */
+ PRIVATE,
+
+ }
+
+ private static final String PKCS8 = "PKCS#8";
+ private static final String X509 = "X.509";
+ private static final String RAW = "RAW";
+
+ /**
+ * Either one of Type.SECRET, Type.PUBLIC, or Type.PRIVATE
+ *
+ * @serial
+ */
+ private Type type;
+
+ /**
+ * The Key algorithm
+ *
+ * @serial
+ */
+ private String algorithm;
+
+ /**
+ * The Key encoding format
+ *
+ * @serial
+ */
+ private String format;
+
+ /**
+ * The encoded Key bytes
+ *
+ * @serial
+ */
+ private byte[] encoded;
+
+ /**
+ * Construct the alternate Key class.
+ *
+ * <p>
+ *
+ * @param type either one of Type.SECRET, Type.PUBLIC, or Type.PRIVATE
+ * @param algorithm the algorithm returned from
+ * <code>Key.getAlgorithm()</code>
+ * @param format the encoding format returned from
+ * <code>Key.getFormat()</code>
+ * @param encoded the encoded bytes returned from
+ * <code>Key.getEncoded()</code>
+ *
+ * @exception NullPointerException
+ * if type is <code>null</code>,
+ * if algorithm is <code>null</code>,
+ * if format is <code>null</code>,
+ * or if encoded is <code>null</code>
+ */
+ public KeyRep(Type type, String algorithm,
+ String format, byte[] encoded) {
+
+ if (type == null || algorithm == null ||
+ format == null || encoded == null) {
+ throw new NullPointerException("invalid null input(s)");
+ }
+
+ this.type = type;
+ this.algorithm = algorithm;
+ this.format = format.toUpperCase();
+ this.encoded = (byte[])encoded.clone();
+ }
+
+ /**
+ * Resolve the Key object.
+ *
+ * <p> This method supports three Type/format combinations:
+ * <ul>
+ * <li> Type.SECRET/"RAW" - returns a SecretKeySpec object
+ * constructed using encoded key bytes and algorithm
+ * <li> Type.PUBLIC/"X.509" - gets a KeyFactory instance for
+ * the key algorithm, constructs an X509EncodedKeySpec with the
+ * encoded key bytes, and generates a public key from the spec
+ * <li> Type.PRIVATE/"PKCS#8" - gets a KeyFactory instance for
+ * the key algorithm, constructs a PKCS8EncodedKeySpec with the
+ * encoded key bytes, and generates a private key from the spec
+ * </ul>
+ *
+ * <p>
+ *
+ * @return the resolved Key object
+ *
+ * @exception ObjectStreamException if the Type/format
+ * combination is unrecognized, if the algorithm, key format, or
+ * encoded key bytes are unrecognized/invalid, of if the
+ * resolution of the key fails for any reason
+ */
+ protected Object readResolve() throws ObjectStreamException {
+ try {
+ if (type == Type.SECRET && RAW.equals(format)) {
+ return new SecretKeySpec(encoded, algorithm);
+ } else if (type == Type.PUBLIC && X509.equals(format)) {
+ KeyFactory f = KeyFactory.getInstance(algorithm);
+ return f.generatePublic(new X509EncodedKeySpec(encoded));
+ } else if (type == Type.PRIVATE && PKCS8.equals(format)) {
+ KeyFactory f = KeyFactory.getInstance(algorithm);
+ return f.generatePrivate(new PKCS8EncodedKeySpec(encoded));
+ } else {
+ throw new NotSerializableException
+ ("unrecognized type/format combination: " +
+ type + "/" + format);
+ }
+ } catch (NotSerializableException nse) {
+ throw nse;
+ } catch (Exception e) {
+ NotSerializableException nse = new NotSerializableException
+ ("java.security.Key: " +
+ "[" + type + "] " +
+ "[" + algorithm + "] " +
+ "[" + format + "]");
+ nse.initCause(e);
+ throw nse;
+ }
+ }
+}
Added: trunk/core/src/openjdk/java/java/security/Provider.java
===================================================================
--- trunk/core/src/openjdk/java/java/security/Provider.java (rev 0)
+++ trunk/core/src/openjdk/java/java/security/Provider.java 2007-06-23 04:52:58 UTC (rev 3287)
@@ -0,0 +1,1481 @@
+/*
+ * Copyright 1996-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.security;
+
+import java.io.*;
+import java.util.*;
+import static java.util.Locale.ENGLISH;
+import java.lang.ref.*;
+import java.lang.reflect.*;
+
+import java.security.cert.CertStoreParameters;
+import javax.security.auth.login.Configuration;
+
+/**
+ * This class represents a "provider" for the
+ * Java Security API, where a provider implements some or all parts of
+ * Java Security. Services that a provider may implement include:
+ *
+ * <ul>
+ *
+ * <li>Algorithms (such as DSA, RSA, MD5 or SHA-1).
+ *
+ * <li>Key generation, conversion, and management facilities (such as for
+ * algorithm-specific keys).
+ *
+ *</ul>
+ *
+ * <p>Each provider has a name and a version number, and is configured
+ * in each runtime it is installed in.
+ *
+ * <p>See <a href =
+ * "../../../technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
+ * in the "Java Cryptography Architecture API Specification & Reference"
+ * for information about how a particular type of provider, the
+ * cryptographic service provider, works and is installed. However,
+ * please note that a provider can be used to implement any security
+ * service in Java that uses a pluggable architecture with a choice
+ * of implementations that fit underneath.
+ *
+ * <p>Some provider implementations may encounter unrecoverable internal
+ * errors during their operation, for example a failure to communicate with a
+ * security token. A {@link ProviderException} should be used to indicate
+ * such errors.
+ *
+ * <p>The service type <code>Provider</code> is reserved for use by the
+ * security framework. Services of this type cannot be added, removed,
+ * or modified by applications.
+ * The following attributes are automatically placed in each Provider object:
+ * <table cellspacing=4>
+ * <tr><th>Name</th><th>Value</th>
+ * <tr><td><code>Provider.id name</code></td>
+ * <td><code>String.valueOf(provider.getName())</code></td>
+ * <tr><td><code>Provider.id version</code></td>
+ * <td><code>String.valueOf(provider.getVersion())</code></td>
+ * <tr><td><code>Provider.id info</code></td>
+ <td><code>String.valueOf(provider.getInfo())</code></td>
+ * <tr><td><code>Provider.id className</code></td>
+ * <td><code>provider.getClass().getName()</code></td>
+ * </table>
+ *
+ * @version 1.84, 05/05/07
+ * @author Benjamin Renaud
+ * @author Andreas Sterbenz
+ */
+public abstract class Provider extends Properties {
+
+ // Declare serialVersionUID to be compatible with JDK1.1
+ static final long serialVersionUID = -4298000515446427739L;
+
+ private static final sun.security.util.Debug debug =
+ sun.security.util.Debug.getInstance
+ ("provider", "Provider");
+
+ /**
+ * The provider name.
+ *
+ * @serial
+ */
+ private String name;
+
+ /**
+ * A description of the provider and its services.
+ *
+ * @serial
+ */
+ private String info;
+
+ /**
+ * The provider version number.
+ *
+ * @serial
+ */
+ private double version;
+
+
+ private transient Set<Map.Entry<Object,Object>> entrySet = null;
+ private transient int entrySetCallCount = 0;
+
+ private transient boolean initialized;
+
+ /**
+ * Constructs a provider with the specified name, version number,
+ * and information.
+ *
+ * @param name the provider name.
+ *
+ * @param version the provider version number.
+ *
+ * @param info a description of the provider and its services.
+ */
+ protected Provider(String name, double version, String info) {
+ this.name = name;
+ this.version = version;
+ this.info = info;
+ putId();
+ initialized = true;
+ }
+
+ /**
+ * Returns the name of this provider.
+ *
+ * @return the name of this provider.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the version number for this provider.
+ *
+ * @return the version number for this provider.
+ */
+ public double getVersion() {
+ return version;
+ }
+
+ /**
+ * Returns a human-readable description of the provider and its
+ * services. This may return an HTML page, with relevant links.
+ *
+ * @return a description of the provider and its services.
+ */
+ public String getInfo() {
+ return info;
+ }
+
+ /**
+ * Returns a string with the name and the version number
+ * of this provider.
+ *
+ * @return the string with the name and the version number
+ * for this provider.
+ */
+ public String toString() {
+ return name + " version " + version;
+ }
+
+ /*
+ * override the following methods to ensure that provider
+ * information can only be changed if the caller has the appropriate
+ * permissions.
+ */
+
+ /**
+ * Clears this provider so that it no longer contains the properties
+ * used to look up facilities implemented by the provider.
+ *
+ * <p>First, if there is a security manager, its
+ * <code>checkSecurityAccess</code> method is called with the string
+ * <code>"clearProviderProperties."+name</code> (where <code>name</code>
+ * is the provider name) to see if it's ok to clear this provider.
+ * If the default implementation of <code>checkSecurityAccess</code>
+ * is used (that is, that method is not overriden), then this results in
+ * a call to the security manager's <code>checkPermission</code> method
+ * with a <code>SecurityPermission("clearProviderProperties."+name)</code>
+ * permission.
+ *
+ * @throws SecurityException
+ * if a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkSecurityAccess}</code> method
+ * denies access to clear this provider
+ *
+ * @since 1.2
+ */
+ public synchronized void clear() {
+ check("clearProviderProperties."+name);
+ if (debug != null) {
+ debug.println("Remove " + name + " provider properties");
+ }
+ implClear();
+ }
+
+ /**
+ * Reads a property list (key and element pairs) from the input stream.
+ *
+ * @param inStream the input stream.
+ * @exception IOException if an error occurred when reading from the
+ * input stream.
+ * @see java.util.Properties#load
+ */
+ public synchronized void load(InputStream inStream) throws IOException {
+ check("putProviderProperty."+name);
+ if (debug != null) {
+ debug.println("Load " + name + " provider properties");
+ }
+ Properties tempProperties = new Properties();
+ tempProperties.load(inStream);
+ implPutAll(tempProperties);
+ }
+
+ /**
+ * Copies all of the mappings from the specified Map to this provider.
+ * These mappings will replace any properties that this provider had
+ * for any of the keys currently in the specified Map.
+ *
+ * @since 1.2
+ */
+ public synchronized void putAll(Map<?,?> t) {
+ check("putProviderProperty."+name);
+ if (debug != null) {
+ debug.println("Put all " + name + " provider properties");
+ }
+ implPutAll(t);
+ }
+
+ /**
+ * Returns an unmodifiable Set view of the property entries contained
+ * in this Provider.
+ *
+ * @see java.util.Map.Entry
+ * @since 1.2
+ */
+ public synchronized Set<Map.Entry<Object,Object>> entrySet() {
+ checkInitialized();
+ if (entrySet == null) {
+ if (entrySetCallCount++ == 0) // Initial call
+ entrySet = Collections.unmodifiableMap(this).entrySet();
+ else
+ return super.entrySet(); // Recursive call
+ }
+
+ // This exception will be thrown if the implementation of
+ // Collections.unmodifiableMap.entrySet() is changed such that it
+ // no longer calls entrySet() on the backing Map. (Provider's
+ // entrySet implementation depends on this "implementation detail",
+ // which is unlikely to change.
+ if (entrySetCallCount != 2)
+ throw new RuntimeException("Internal error.");
+
+ return entrySet;
+ }
+
+ /**
+ * Returns an unmodifiable Set view of the property keys contained in
+ * this provider.
+ *
+ * @since 1.2
+ */
+ public Set<Object> keySet() {
+ checkInitialized();
+ return Collections.unmodifiableSet(super.keySet());
+ }
+
+ /**
+ * Returns an unmodifiable Collection view of the property values
+ * contained in this provider.
+ *
+ * @since 1.2
+ */
+ public Collection<Object> values() {
+ checkInitialized();
+ return Collections.unmodifiableCollection(super.values());
+ }
+
+ /**
+ * Sets the <code>key</code> property to have the specified
+ * <code>value</code>.
+ *
+ * <p>First, if there is a security manager, its
+ * <code>checkSecurityAccess</code> method is called with the string
+ * <code>"putProviderProperty."+name</code>, where <code>name</code> is the
+ * provider name, to see if it's ok to set this provider's property values.
+ * If the default implementation of <code>checkSecurityAccess</code>
+ * is used (that is, that method is not overriden), then this results in
+ * a call to the security manager's <code>checkPermission</code> method
+ * with a <code>SecurityPermission("putProviderProperty."+name)</code>
+ * permission.
+ *
+ * @param key the property key.
+ *
+ * @param value the property value.
+ *
+ * @return the previous value of the specified property
+ * (<code>key</code>), or null if it did not have one.
+ *
+ * @throws SecurityException
+ * if a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkSecurityAccess}</code> method
+ * denies access to set property values.
+ *
+ * @since 1.2
+ */
+ public synchronized Object put(Object key, Object value) {
+ check("putProviderProperty."+name);
+ if (debug != null) {
+ debug.println("Set " + name + " provider property [" +
+ key + "/" + value +"]");
+ }
+ return implPut(key, value);
+ }
+
+ /**
+ * Removes the <code>key</code> property (and its corresponding
+ * <code>value</code>).
+ *
+ * <p>First, if there is a security manager, its
+ * <code>checkSecurityAccess</code> method is called with the string
+ * <code>"removeProviderProperty."+name</code>, where <code>name</code> is
+ * the provider name, to see if it's ok to remove this provider's
+ * properties. If the default implementation of
+ * <code>checkSecurityAccess</code> is used (that is, that method is not
+ * overriden), then this results in a call to the security manager's
+ * <code>checkPermission</code> method with a
+ * <code>SecurityPermission("removeProviderProperty."+name)</code>
+ * permission.
+ *
+ * @param key the key for the property to be removed.
+ *
+ * @return the value to which the key had been mapped,
+ * or null if the key did not have a mapping.
+ *
+ * @throws SecurityException
+ * if a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkSecurityAccess}</code> method
+ * denies access to remove this provider's properties.
+ *
+ * @since 1.2
+ */
+ public synchronized Object remove(Object key) {
+ check("removeProviderProperty."+name);
+ if (debug != null) {
+ debug.println("Remove " + name + " provider property " + key);
+ }
+ return implRemove(key);
+ }
+
+ // let javadoc show doc from superclass
+ public Object get(Object key) {
+ checkInitialized();
+ return super.get(key);
+ }
+
+ // let javadoc show doc from superclass
+ public Enumeration<Object> keys() {
+ checkInitialized();
+ return super.keys();
+ }
+
+ // let javadoc show doc from superclass
+ public Enumeration<Object> elements() {
+ checkInitialized();
+ return super.elements();
+ }
+
+ // let javadoc show doc from superclass
+ public String getProperty(String key) {
+ checkInitialized();
+ return super.getProperty(key);
+ }
+
+ private void checkInitialized() {
+ if (!initialized) {
+ throw new IllegalStateException();
+ }
+ }
+
+ private void check(String directive) {
+ checkInitialized();
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkSecurityAccess(directive);
+ }
+ }
+
+ // legacy properties changed since last call to any services method?
+ private transient boolean legacyChanged;
+ // serviceMap changed since last call to getServices()
+ private transient boolean servicesChanged;
+
+ // Map<String,String>
+ private transient Map<String,String> legacyStrings;
+
+ // Map<ServiceKey,Service>
+ // used for services added via putService(), initialized on demand
+ private transient Map<ServiceKey,Service> serviceMap;
+
+ // Map<ServiceKey,Service>
+ // used for services added via legacy methods, init on demand
+ private transient Map<ServiceKey,Service> legacyMap;
+
+ // Set<Service>
+ // Unmodifiable set of all services. Initialized on demand.
+ private transient Set<Service> serviceSet;
+
+ // register the id attributes for this provider
+ // this is to ensure that equals() and hashCode() do not incorrectly
+ // report to different provider objects as the same
+ private void putId() {
+ // note: name and info may be null
+ super.put("Provider.id name", String.valueOf(name));
+ super.put("Provider.id version", String.valueOf(version));
+ super.put("Provider.id info", String.valueOf(info));
+ super.put("Provider.id className", this.getClass().getName());
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ Map<Object,Object> copy = new HashMap<Object,Object>();
+ for (Map.Entry<Object,Object> entry : super.entrySet()) {
+ copy.put(entry.getKey(), entry.getValue());
+ }
+ defaults = null;
+ in.defaultReadObject();
+ implClear();
+ initialized = true;
+ putAll(copy);
+ }
+
+ /**
+ * Copies all of the mappings from the specified Map to this provider.
+ * Internal method to be called AFTER the security check has been
+ * performed.
+ */
+ private void implPutAll(Map t) {
+ for (Map.Entry e : ((Map<?,?>)t).entrySet()) {
+ implPut(e.getKey(), e.getValue());
+ }
+ }
+
+ private Object implRemove(Object key) {
+ if (key instanceof String) {
+ String keyString = (String)key;
+ if (keyString.startsWith("Provider.")) {
+ return null;
+ }
+ legacyChanged = true;
+ if (legacyStrings == null) {
+ legacyStrings = new LinkedHashMap<String,String>();
+ }
+ legacyStrings.remove(keyString);
+ }
+ return super.remove(key);
+ }
+
+ private Object implPut(Object key, Object value) {
+ if ((key instanceof String) && (value instanceof String)) {
+ String keyString = (String)key;
+ if (keyString.startsWith("Provider.")) {
+ return null;
+ }
+ legacyChanged = true;
+ if (legacyStrings == null) {
+ legacyStrings = new LinkedHashMap<String,String>();
+ }
+ legacyStrings.put(keyString, (String)value);
+ }
+ return super.put(key, value);
+ }
+
+ private void implClear() {
+ if (legacyStrings != null) {
+ legacyStrings.clear();
+ }
+ if (legacyMap != null) {
+ legacyMap.clear();
+ }
+ if (serviceMap != null) {
+ serviceMap.clear();
+ }
+ legacyChanged = false;
+ servicesChanged = false;
+ serviceSet = null;
+ super.clear();
+ putId();
+ }
+
+ // used as key in the serviceMap and legacyMap HashMaps
+ private static class ServiceKey {
+ private final String type;
+ private final String algorithm;
+ private final String originalAlgorithm;
+ private ServiceKey(String type, String algorithm, boolean intern) {
+ this.type = type;
+ this.originalAlgorithm = algorithm;
+ algorithm = algorithm.toUpperCase(ENGLISH);
+ this.algorithm = intern ? algorithm.intern() : algorithm;
+ }
+ public int hashCode() {
+ return type.hashCode() + algorithm.hashCode();
+ }
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ServiceKey == false) {
+ return false;
+ }
+ ServiceKey other = (ServiceKey)obj;
+ return this.type.equals(other.type)
+ && this.algorithm.equals(other.algorithm);
+ }
+ boolean matches(String type, String algorithm) {
+ return (this.type == type) && (this.originalAlgorithm == algorithm);
+ }
+ }
+
+ /**
+ * Ensure all the legacy String properties are fully parsed into
+ * service objects.
+ */
+ private void ensureLegacyParsed() {
+ if ((legacyChanged == false) || (legacyStrings == null)) {
+ return;
+ }
+ serviceSet = null;
+ if (legacyMap == null) {
+ legacyMap = new LinkedHashMap<ServiceKey,Service>();
+ } else {
+ legacyMap.clear();
+ }
+ for (Map.Entry<String,String> entry : legacyStrings.entrySet()) {
+ parseLegacyPut(entry.getKey(), entry.getValue());
+ }
+ removeInvalidServices(legacyMap);
+ legacyChanged = false;
+ }
+
+ /**
+ * Remove all invalid services from the Map. Invalid services can only
+ * occur if the legacy properties are inconsistent or incomplete.
+ */
+ private void removeInvalidServices(Map<ServiceKey,Service> map) {
+ for (Iterator t = map.entrySet().iterator(); t.hasNext(); ) {
+ Map.Entry entry = (Map.Entry)t.next();
+ Service s = (Service)entry.getValue();
+ if (s.isValid() == false) {
+ t.remove();
+ }
+ }
+ }
+
+ private String[] getTypeAndAlgorithm(String key) {
+ int i = key.indexOf(".");
+ if (i < 1) {
+ if (debug != null) {
+ debug.println("Ignoring invalid entry in provider "
+ + name + ":" + key);
+ }
+ return null;
+ }
+ String type = key.substring(0, i);
+ String alg = key.substring(i + 1);
+ return new String[] {type, alg};
+ }
+
+ private final static String ALIAS_PREFIX = "Alg.Alias.";
+ private final static String ALIAS_PREFIX_LOWER = "alg.alias.";
+ private final static int ALIAS_LENGTH = ALIAS_PREFIX.length();
+
+ private void parseLegacyPut(String name, String value) {
+ if (name.toLowerCase(ENGLISH).startsWith(ALIAS_PREFIX_LOWER)) {
+ // e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1");
+ // aliasKey ~ MessageDigest.SHA
+ String stdAlg = value;
+ String aliasKey = name.substring(ALIAS_LENGTH);
+ String[] typeAndAlg = getTypeAndAlgorithm(aliasKey);
+ if (typeAndAlg == null) {
+ return;
+ }
+ String type = getEngineName(typeAndAlg[0]);
+ String aliasAlg = typeAndAlg[1].intern();
+ ServiceKey key = new ServiceKey(type, stdAlg, true);
+ Service s = (Service)legacyMap.get(key);
+ if (s == null) {
+ s = new Service(this);
+ s.type = type;
+ s.algorithm = stdAlg;
+ legacyMap.put(key, s);
+ }
+ legacyMap.put(new ServiceKey(type, aliasAlg, true), s);
+ s.addAlias(aliasAlg);
+ } else {
+ String[] typeAndAlg = getTypeAndAlgorithm(name);
+ if (typeAndAlg == null) {
+ return;
+ }
+ int i = typeAndAlg[1].indexOf(' ');
+ if (i == -1) {
+ // e.g. put("MessageDigest.SHA-1", "sun.security.provider.SHA");
+ String type = getEngineName(typeAndAlg[0]);
+ String stdAlg = typeAndAlg[1].intern();
+ String className = value;
+ ServiceKey key = new ServiceKey(type, stdAlg, true);
+ Service s = (Service)legacyMap.get(key);
+ if (s == null) {
+ s = new Service(this);
+ s.type = type;
+ s.algorithm = stdAlg;
+ legacyMap.put(key, s);
+ }
+ s.className = className;
+ } else { // attribute
+ // e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software");
+ String attributeValue = value;
+ String type = getEngineName(typeAndAlg[0]);
+ String attributeString = typeAndAlg[1];
+ String stdAlg = attributeString.substring(0, i).intern();
+ String attributeName = attributeString.substring(i + 1);
+ // kill additional spaces
+ while (attributeName.startsWith(" ")) {
+ attributeName = attributeName.substring(1);
+ }
+ attributeName = attributeName.intern();
+ ServiceKey key = new ServiceKey(type, stdAlg, true);
+ Service s = (Service)legacyMap.get(key);
+ if (s == null) {
+ s = new Service(this);
+ s.type = type;
+ s.algorithm = stdAlg;
+ legacyMap.put(key, s);
+ }
+ s.addAttribute(attributeName, attributeValue);
+ }
+ }
+ }
+
+ /**
+ * Get the service describing this Provider's implementation of the
+ * specified type of this algorithm or alias. If no such
+ * implementation exists, this method returns null. If there are two
+ * matching services, one added to this provider using
+ * {@link #putService putService()} and one added via {@link #put put()},
+ * the service added via {@link #putService putService()} is returned.
+ *
+ * @param type the type of {@link Service service} requested
+ * (for example, <code>MessageDigest</code>)
+ * @param algorithm the case insensitive algorithm name (or alternate
+ * alias) of the service requested (for example, <code>SHA-1</code>)
+ *
+ * @return the service describing this Provider's matching service
+ * or null if no such service exists
+ *
+ * @throws NullPointerException if type or algorithm is null
+ *
+ * @since 1.5
+ */
+ public synchronized Service getService(String type, String algorithm) {
+ checkInitialized();
+ // avoid allocating a new key object if possible
+ ServiceKey key = previousKey;
+ if (key.matches(type, algorithm) == false) {
+ key = new ServiceKey(type, algorithm, false);
+ previousKey = key;
+ }
+ if (serviceMap != null) {
+ Service service = serviceMap.get(key);
+ if (service != null) {
+ return service;
+ }
+ }
+ ensureLegacyParsed();
+ return (legacyMap != null) ? legacyMap.get(key) : null;
+ }
+
+ // ServiceKey from previous getService() call
+ // by re-using it if possible we avoid allocating a new object
+ // and the toUpperCase() call.
+ // re-use will occur e.g. as the framework traverses the provider
+ // list and queries each provider with the same values until it finds
+ // a matching service
+ private static volatile ServiceKey previousKey =
+ new ServiceKey("", "", false);
+
+ /**
+ * Get an unmodifiable Set of all services supported by
+ * this Provider.
+ *
+ * @return an unmodifiable Set of all services supported by
+ * this Provider
+ *
+ * @since 1.5
+ */
+ public synchronized Set<Service> getServices() {
+ checkInitialized();
+ if (legacyChanged || servicesChanged) {
+ serviceSet = null;
+ }
+ if (serviceSet == null) {
+ ensureLegacyParsed();
+ Set<Service> set = new LinkedHashSet<Service>();
+ if (serviceMap != null) {
+ set.addAll(serviceMap.values());
+ }
+ if (legacyMap != null) {
+ set.addAll(legacyMap.values());
+ }
+ serviceSet = Collections.unmodifiableSet(set);
+ servicesChanged = false;
+ }
+ return serviceSet;
+ }
+
+ /**
+ * Add a service. If a service of the same type with the same algorithm
+ * name exists and it was added using {@link #putService putService()},
+ * it is replaced by the new service.
+ * This method also places information about this service
+ * in the provider's Hashtable values in the format described in the
+ * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
+ * Java Cryptography Architecture API Specification & Reference </a>.
+ *
+ * <p>Also, if there is a security manager, its
+ * <code>checkSecurityAccess</code> method is called with the string
+ * <code>"putProviderProperty."+name</code>, where <code>name</code> is
+ * the provider name, to see if it's ok to set this provider's property
+ * values. If the default implementation of <code>checkSecurityAccess</code>
+ * is used (that is, that method is not overriden), then this results in
+ * a call to the security manager's <code>checkPermission</code> method with
+ * a <code>SecurityPermission("putProviderProperty."+name)</code>
+ * permission.
+ *
+ * @param s the Service to add
+ *
+ * @throws SecurityException
+ * if a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkSecurityAccess}</code> method denies
+ * access to set property values.
+ * @throws NullPointerException if s is null
+ *
+ * @since 1.5
+ */
+ protected synchronized void putService(Service s) {
+ check("putProviderProperty." + name);
+ if (debug != null) {
+ debug.println(name + ".putService(): " + s);
+ }
+ if (s == null) {
+ throw new NullPointerException();
+ }
+ if (s.getProvider() != this) {
+ throw new IllegalArgumentException
+ ("service.getProvider() must match this Provider object");
+ }
+ if (serviceMap == null) {
+ serviceMap = new LinkedHashMap<ServiceKey,Service>();
+ }
+ servicesChanged = true;
+ String type = s.getType();
+ String algorithm = s.getAlgorithm();
+ ServiceKey key = new ServiceKey(type, algorithm, true);
+ // remove existing service
+ implRemoveService(serviceMap.get(key));
+ serviceMap.put(key, s);
+ for (String alias : s.getAliases()) {
+ serviceMap.put(new ServiceKey(type, alias, true), s);
+ }
+ putPropertyStrings(s);
+ }
+
+ /**
+ * Put the string properties for this Service in this Provider's
+ * Hashtable.
+ */
+ private void putPropertyStrings(Service s) {
+ String type = s.getType();
+ String algorithm = s.getAlgorithm();
+ // use super() to avoid permission check and other processing
+ super.put(type + "." + algorithm, s.getClassName());
+ for (String alias : s.getAliases()) {
+ super.put(ALIAS_PREFIX + type + "." + alias, algorithm);
+ }
+ for (Map.Entry<UString,String> entry : s.attributes.entrySet()) {
+ String key = type + "." + algorithm + " " + entry.getKey();
+ super.put(key, entry.getValue());
+ }
+ }
+
+ /**
+ * Remove the string properties for this Service from this Provider's
+ * Hashtable.
+ */
+ private void removePropertyStrings(Service s) {
+ String type = s.getType();
+ String algorithm = s.getAlgorithm();
+ // use super() to avoid permission check and other processing
+ super.remove(type + "." + algorithm);
+ for (String alias : s.getAliases()) {
+ super.remove(ALIAS_PREFIX + type + "." + alias);
+ }
+ for (Map.Entry<UString,String> entry : s.attributes.entrySet()) {
+ String key = type + "." + algorithm + " " + entry.getKey();
+ super.remove(key);
+ }
+ }
+
+ /**
+ * Remove a service previously added using
+ * {@link #putService putService()}. The specified service is removed from
+ * this provider. It will no longer be returned by
+ * {@link #getService getService()} and its information will be removed
+ * from this provider's Hashtable.
+ *
+ * <p>Also, if there is a security manager, its
+ * <code>checkSecurityAccess</code> method is called with the string
+ * <code>"removeProviderProperty."+name</code>, where <code>name</code> is
+ * the provider name, to see if it's ok to remove this provider's
+ * properties. If the default implementation of
+ * <code>checkSecurityAccess</code> is used (that is, that method is not
+ * overriden), then this results in a call to the security manager's
+ * <code>checkPermission</code> method with a
+ * <code>SecurityPermission("removeProviderProperty."+name)</code>
+ * permission.
+ *
+ * @param s the Service to be removed
+ *
+ * @throws SecurityException
+ * if a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkSecurityAccess}</code> method denies
+ * access to remove this provider's properties.
+ * @throws NullPointerException if s is null
+ *
+ * @since 1.5
+ */
+ protected synchronized void removeService(Service s) {
+ check("removeProviderProperty." + name);
+ if (debug != null) {
+ debug.println(name + ".removeService(): " + s);
+ }
+ if (s == null) {
+ throw new NullPointerException();
+ }
+ implRemoveService(s);
+ }
+
+ private void implRemoveService(Service s) {
+ if ((s == null) || (serviceMap == null)) {
+ return;
+ }
+ String type = s.getType();
+ String algorithm = s.getAlgorithm();
+ ServiceKey key = new ServiceKey(type, algorithm, false);
+ Service oldService = serviceMap.get(key);
+ if (s != oldService) {
+ return;
+ }
+ servicesChanged = true;
+ serviceMap.remove(key);
+ for (String alias : s.getAliases()) {
+ serviceMap.remove(new ServiceKey(type, alias, false));
+ }
+ removePropertyStrings(s);
+ }
+
+ // Wrapped String that behaves in a case insensitive way for equals/hashCode
+ private static class UString {
+ final String string;
+ final String lowerString;
+
+ UString(String s) {
+ this.string = s;
+ this.lowerString = s.toLowerCase(ENGLISH);
+ }
+
+ public int hashCode() {
+ return lowerString.hashCode();
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof UString == false) {
+ return false;
+ }
+ UString other = (UString)obj;
+ return lowerString.equals(other.lowerString);
+ }
+
+ public String toString() {
+ return string;
+ }
+ }
+
+ // describe relevant properties of a type of engine
+ private static class EngineDescription {
+ final String name;
+ final boolean supportsParameter;
+ final String constructorParameterClassName;
+ private volatile Class constructorParameterClass;
+
+ EngineDescription(String name, boolean sp, String paramName) {
+ this.name = name;
+ this.supportsParameter = sp;
+ this.constructorParameterClassName = paramName;
+ }
+ Class getConstructorParameterClass() throws ClassNotFoundException {
+ Class clazz = constructorParameterClass;
+ if (clazz == null) {
+ clazz = Class.forName(constructorParameterClassName);
+ constructorParameterClass = clazz;
+ }
+ return clazz;
+ }
+ }
+
+ // built in knowledge of the engine types shipped as part of the JDK
+ private static final Map<String,EngineDescription> knownEngines;
+
+ private static void addEngine(String name, boolean sp, String paramName) {
+ EngineDescription ed = new EngineDescription(name, sp, paramName);
+ // also index by canonical name to avoid toLowerCase() for some lookups
+ knownEngines.put(name.toLowerCase(ENGLISH), ed);
+ knownEngines.put(name, ed);
+ }
+
+ static {
+ knownEngines = new HashMap<String,EngineDescription>();
+ // JCA
+ addEngine("AlgorithmParameterGenerator", false, null);
+ addEngine("AlgorithmParameters", false, null);
+ addEngine("KeyFactory", false, null);
+ addEngine("KeyPairGenerator", false, null);
+ addEngine("KeyStore", false, null);
+ addEngine("MessageDigest", false, null);
+ addEngine("SecureRandom", false, null);
+ addEngine("Signature", true, null);
+ addEngine("CertificateFactory", false, null);
+ addEngine("CertPathBuilder", false, null);
+ addEngine("CertPathValidator", false, null);
+ addEngine("CertStore", false,
+ "java.security.cert.CertStoreParameters");
+ // JCE
+ addEngine("Cipher", true, null);
+ addEngine("ExemptionMechanism", false, null);
+ addEngine("Mac", true, null);
+ addEngine("KeyAgreement", true, null);
+ addEngine("KeyGenerator", false, null);
+ addEngine("SecretKeyFactory", false, null);
+ // JSSE
+ addEngine("KeyManagerFactory", false, null);
+ addEngine("SSLContext", false, null);
+ addEngine("TrustManagerFactory", false, null);
+ // JGSS
+ addEngine("GssApiMechanism", false, null);
+ // SASL
+ addEngine("SaslClientFactory", false, null);
+ addEngine("SaslServerFactory", false, null);
+ // POLICY
+ addEngine("Policy", false,
+ "java.security.Policy$Parameters");
+ // CONFIGURATION
+ addEngine("Configuration", false,
+ "javax.security.auth.login.Configuration$Parameters");
+ // XML DSig
+ addEngine("XMLSignatureFactory", false, null);
+ addEngine("KeyInfoFactory", false, null);
+ addEngine("TransformService", false, null);
+ // Smart Card I/O
+ addEngine("TerminalFactory", false,
+ "java.lang.Object");
+ }
+
+ // get the "standard" (mixed-case) engine name for arbitary case engine name
+ // if there is no known engine by that name, return s
+ private static String getEngineName(String s) {
+ // try original case first, usually correct
+ EngineDescription e = knownEngines.get(s);
+ if (e == null) {
+ e = knownEngines.get(s.toLowerCase(ENGLISH));
+ }
+ return (e == null) ? s : e.name;
+ }
+
+ /**
+ * The description of a security service. It encapsulates the properties
+ * of a service and contains a factory method to obtain new implementation
+ * instances of this service.
+ *
+ * <p>Each service has a provider that offers the service, a type,
+ * an algorithm name, and the name of the class that implements the
+ * service. Optionally, it also includes a list of alternate ...
[truncated message content] |