From 6f5ce93bab1c1ce6df0e71aa450f841f3d979bbc Mon Sep 17 00:00:00 2001
From: Andreas Tobler Use of this class requires extensive knowledge of the Internet
+ * Engineering Task Force's Public Key Infrastructure (X.509). The primary
+ * document describing this standard is RFC 3280: Internet X.509
+ * Public Key Infrastructure Certificate and Certificate Revocation List
+ * (CRL) Profile.
+ *
+ * Note that this class is not thread-safe. If multiple threads will
+ * use or modify this class then they need to synchronize on the object.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class X509CRLSelector implements CRLSelector, Cloneable
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private static final String CRL_NUMBER_ID = "2.5.29.20";
+
+ private List issuerNames;
+ private BigInteger maxCrlNumber;
+ private BigInteger minCrlNumber;
+ private Date date;
+ private X509Certificate cert;
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Creates a new CRL selector with no criteria enabled; i.e., every CRL
+ * will be matched.
+ */
+ public X509CRLSelector()
+ {
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Add an issuer name to the set of issuer names criteria, as the DER
+ * encoded form.
+ *
+ * @param name The name to add, as DER bytes.
+ * @throws IOException If the argument is not a valid DER-encoding.
+ */
+ public void addIssuerName(byte[] name) throws IOException
+ {
+ X500Principal p = null;
+ try
+ {
+ p = new X500Principal(name);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ IOException ioe = new IOException("malformed name");
+ ioe.initCause(iae);
+ throw ioe;
+ }
+ if (issuerNames == null)
+ issuerNames = new LinkedList();
+ issuerNames.add(p);
+ }
+
+ /**
+ * Add an issuer name to the set of issuer names criteria, as a
+ * String representation.
+ *
+ * @param name The name to add.
+ * @throws IOException If the argument is not a valid name.
+ */
+ public void addIssuerName(String name) throws IOException
+ {
+ X500Principal p = null;
+ try
+ {
+ p = new X500Principal(name);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ IOException ioe = new IOException("malformed name: " + name);
+ ioe.initCause(iae);
+ throw ioe;
+ }
+ if (issuerNames == null)
+ issuerNames = new LinkedList();
+ issuerNames.add(p);
+ }
+
+ /**
+ * Sets the issuer names criterion. Pass Use of this class requires extensive knowledge of the Internet
+ * Engineering Task Force's Public Key Infrastructure (X.509). The primary
+ * document describing this standard is RFC 3280: Internet X.509
+ * Public Key Infrastructure Certificate and Certificate Revocation List
+ * (CRL) Profile.
+ *
+ * Note that this class is not thread-safe. If multiple threads will
+ * use or modify this class then they need to synchronize on the object.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class X509CertSelector implements CertSelector, Cloneable
+{
+
+ // Constants and fields.
+ // -------------------------------------------------------------------------
+
+ private static final String AUTH_KEY_ID = "2.5.29.35";
+ private static final String SUBJECT_KEY_ID = "2.5.29.14";
+ private static final String NAME_CONSTRAINTS_ID = "2.5.29.30";
+
+ private int basicConstraints;
+ private X509Certificate cert;
+ private BigInteger serialNo;
+ private X500Principal issuer;
+ private X500Principal subject;
+ private byte[] subjectKeyId;
+ private byte[] authKeyId;
+ private boolean[] keyUsage;
+ private Date certValid;
+ private OID sigId;
+ private PublicKey subjectKey;
+ private X509EncodedKeySpec subjectKeySpec;
+ private Set keyPurposeSet;
+ private List altNames;
+ private boolean matchAllNames;
+ private byte[] nameConstraints;
+ private Set policy;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Creates a new X.509 certificate selector. The new selector will be
+ * empty, and will accept any certificate (provided that it is an
+ * {@link X509Certificate}).
+ */
+ public X509CertSelector()
+ {
+ basicConstraints = -1;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the certificate criterion, or Do not use this method. It is not deprecated, as it is not deprecated
+ * in the Java standard, but it is basically a no-operation and simply
+ * returns Do not use this method. It is not deprecated, as it is not deprecated
+ * in the Java standard, but it is basically a no-operation.
+ *
+ * @param UNUSED Is silently ignored.
+ */
+ public void setPrivateKeyValid(Date UNUSED)
+ {
+ }
+
+ /**
+ * Returns the public key algorithm ID that matching certificates must have,
+ * or This class implements a cryptographic cipher for transforming
+ * data. Ciphers cannot be instantiated directly; rather one of the
+ * A transformation is of the form: where algorithm is the base name of a cryptographic cipher
+ * (such as "AES"), mode is the abbreviated name of a block
+ * cipher mode (such as "CBC" for cipher block chaining mode), and
+ * padding is the name of a padding scheme (such as
+ * "PKCS5Padding"). If only the algorithm name is supplied, then the
+ * provider-specific default mode and padding will be used. An example transformation is: Finally, when requesting a block cipher in stream cipher mode
+ * (such as AES
+ * in OFB or CFB mode) the number of bits to be processed
+ * at a time may be specified by appending it to the name of the mode;
+ * e.g. Creates a new cipher instance for the given transformation. The installed providers are tried in order for an
+ * implementation, and the first appropriate instance is returned. If
+ * no installed provider can provide the implementation, an
+ * appropriate exception is thrown. Creates a new cipher instance for the given transformation and
+ * the named provider. Initialize this cipher with the public key from the given
+ * certificate. The cipher will be initialized for encryption, decryption, key
+ * wrapping, or key unwrapping, depending upon whether the
+ * As per the Java 1.4 specification, if If this cipher requires any random bytes (for example for an
+ * initilization vector) than the {@link java.security.SecureRandom}
+ * with the highest priority is used as the source of these bytes. A call to any of the Initialize this cipher with the supplied key. The cipher will be initialized for encryption, decryption, key
+ * wrapping, or key unwrapping, depending upon whether the
+ * If this cipher requires any random bytes (for example for an
+ * initilization vector) than the {@link java.security.SecureRandom}
+ * with the highest priority is used as the source of these bytes. A call to any of the Initialize this cipher with the public key from the given
+ * certificate and the specified source of randomness. The cipher will be initialized for encryption, decryption, key
+ * wrapping, or key unwrapping, depending upon whether the
+ * As per the Java 1.4 specification, if If this cipher requires any random bytes (for example for an
+ * initilization vector) than the {@link java.security.SecureRandom}
+ * with the highest priority is used as the source of these bytes. A call to any of the Initialize this cipher with the supplied key and source of
+ * randomness. The cipher will be initialized for encryption, decryption, key
+ * wrapping, or key unwrapping, depending upon whether the
+ * A call to any of the Initialize this cipher with the supplied key and parameters. The cipher will be initialized for encryption, decryption, key
+ * wrapping, or key unwrapping, depending upon whether the
+ * If this cipher requires any random bytes (for example for an
+ * initilization vector) then the {@link java.security.SecureRandom}
+ * with the highest priority is used as the source of these bytes. A call to any of the Initialize this cipher with the supplied key and parameters. The cipher will be initialized for encryption, decryption, key
+ * wrapping, or key unwrapping, depending upon whether the
+ * If this cipher requires any random bytes (for example for an
+ * initilization vector) then the {@link java.security.SecureRandom}
+ * with the highest priority is used as the source of these bytes. A call to any of the Initialize this cipher with the supplied key, parameters, and
+ * source of randomness. The cipher will be initialized for encryption, decryption, key
+ * wrapping, or key unwrapping, depending upon whether the
+ * A call to any of the Initialize this cipher with the supplied key, parameters, and
+ * source of randomness. The cipher will be initialized for encryption, decryption, key
+ * wrapping, or key unwrapping, depending upon whether the
+ * A call to any of the This method will first invoke the {@link Cipher#doFinal()}
+ * method of the underlying {@link Cipher}, and writes the output of
+ * that method to the sink output stream.
+ *
+ * @throws java.io.IOException If an I/O error occurs, or if an error
+ * is caused by finalizing the transformation.
+ */
+ public void close() throws IOException
+ {
+ try
+ {
+ int len;
+ if (state != FIRST_TIME)
+ {
+ len = cipher.update(inBuffer[0], 0, inBuffer[0].length, outBuffer);
+ out.write(outBuffer, 0, len);
+ }
+ len = cipher.doFinal(inBuffer[0], 0, inLength, outBuffer);
+ out.write(outBuffer, 0, len);
+ }
+ catch (javax.crypto.IllegalBlockSizeException ibse)
+ {
+ throw new IOException(ibse.toString());
+ }
+ catch (javax.crypto.BadPaddingException bpe)
+ {
+ throw new IOException(bpe.toString());
+ }
+ catch (ShortBufferException sbe)
+ {
+ throw new IOException(sbe.toString());
+ }
+ out.flush();
+ out.close();
+ }
+
+ /**
+ * Flush any pending output.
+ *
+ * @throws java.io.IOException If an I/O error occurs.
+ */
+ public void flush() throws IOException
+ {
+ out.flush();
+ }
+
+ /**
+ * Write a single byte to the output stream.
+ *
+ * @param b The next byte.
+ * @throws java.io.IOException If an I/O error occurs, or if the
+ * underlying cipher is not in the correct state to transform
+ * data.
+ */
+ public void write(int b) throws IOException
+ {
+ if (isStream)
+ {
+ byte[] buf = new byte[] { (byte) b };
+ try
+ {
+ cipher.update(buf, 0, 1, buf, 0);
+ }
+ catch (ShortBufferException sbe)
+ {
+ throw new IOException(sbe.toString());
+ }
+ out.write(buf);
+ return;
+ }
+ inBuffer[1][inLength++] = (byte) b;
+ if (inLength == inBuffer[1].length)
+ process();
+ }
+
+ /**
+ * Write a byte array to the output stream.
+ *
+ * @param buf The next bytes.
+ * @throws java.io.IOException If an I/O error occurs, or if the
+ * underlying cipher is not in the correct state to transform
+ * data.
+ */
+ public void write(byte[] buf) throws IOException
+ {
+ write(buf, 0, buf.length);
+ }
+
+ /**
+ * Write a portion of a byte array to the output stream.
+ *
+ * @param buf The next bytes.
+ * @param off The offset in the byte array to start.
+ * @param len The number of bytes to write.
+ * @throws java.io.IOException If an I/O error occurs, or if the
+ * underlying cipher is not in the correct state to transform
+ * data.
+ */
+ public void write(byte[] buf, int off, int len) throws IOException
+ {
+ if (isStream)
+ {
+ out.write(cipher.update(buf, off, len));
+ return;
+ }
+ int count = 0;
+ while (count < len)
+ {
+ int l = Math.min(inBuffer[1].length - inLength, len - count);
+ System.arraycopy(buf, off+count, inBuffer[1], inLength, l);
+ count += l;
+ inLength += l;
+ if (inLength == inBuffer[1].length)
+ process();
+ }
+ }
+
+ // Own method.
+ // -------------------------------------------------------------------------
+
+ private void process() throws IOException
+ {
+ if (state == SECOND_TIME)
+ {
+ state = SEASONED;
+ }
+ else
+ {
+ byte[] temp = inBuffer[0];
+ inBuffer[0] = inBuffer[1];
+ inBuffer[1] = temp;
+ }
+ if (state == FIRST_TIME)
+ {
+ inLength = 0;
+ state = SECOND_TIME;
+ return;
+ }
+ try
+ {
+ cipher.update(inBuffer[0], 0, inBuffer[0].length, outBuffer);
+ }
+ catch (ShortBufferException sbe)
+ {
+ throw new IOException(sbe.toString());
+ }
+ out.write(outBuffer);
+ inLength = 0;
+ }
+}
diff --git a/libjava/javax/crypto/CipherSpi.java b/libjava/javax/crypto/CipherSpi.java
new file mode 100644
index 00000000000..06ea534f4f6
--- /dev/null
+++ b/libjava/javax/crypto/CipherSpi.java
@@ -0,0 +1,398 @@
+/* CipherSpi.java -- The cipher service provider interface.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * This class represents the Service Provider Interface
+ * (SPI) for cryptographic ciphers. Providers of cryptographic ciphers must subclass this for every
+ * cipher they implement, implementing the abstract methods as
+ * appropriate, then provide an entry that points to the subclass in
+ * their implementation of {@link java.security.Provider}. CipherSpi objects are instantiated along with {@link Cipher}s when
+ * the {@link Cipher#getInstance(java.lang.String)} methods are invoked.
+ * Particular ciphers are referenced by a transformation, which
+ * is a String consisting of the cipher's name or the ciper's name
+ * followed by a mode and a padding. Transformations all follow the
+ * general form: Cipher names in the master {@link java.security.Provider} class
+ * may be: When any {@link Cipher#getInstance(java.lang.String)} method is
+ * invoked, the following happens if the transformation is simply
+ * algorithm: If the transformation is of the form
+ * algorithm/mode/padding: Return the length of the given key in bits. For compatibility this method is not declared
+ * Returns the size, in bytes, an output buffer must be for a call
+ * to {@link #engineUpdate(byte[],int,int,byte[],int)} or {@link
+ * #engineDoFinal(byte[],int,int,byte[],int)} to succeed. The actual output length may be smaller than the value returned
+ * by this method, as it considers the padding length as well. The
+ * length considered is the argument plus the length of any buffered,
+ * unprocessed bytes. Unwraps a previously-wrapped key. For compatibility this method is not declared
+ * Wrap a key. For compatibility this method is not declared
+ * The ASN.1 type The The Implementation note: this class is present for
+ * API-compatibility only; it is not actually used anywhere in this library
+ * and this library does not, in general, support crypto weakening.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class ExemptionMechanism
+{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------------
+
+ private static final String SERVICE = "ExemptionMechanism";
+ private ExemptionMechanismSpi emSpi;
+ private Provider provider;
+ private String mechanism;
+ private boolean virgin;
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ protected ExemptionMechanism(ExemptionMechanismSpi emSpi, Provider provider,
+ String mechanism)
+ {
+ this.emSpi = emSpi;
+ this.provider = provider;
+ this.mechanism = mechanism;
+ virgin = true;
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------------
+
+ public static final ExemptionMechanism getInstance(String mechanism)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] provs = Security.getProviders();
+ String msg = "";
+ for (int i = 0; i < provs.length; i++)
+ {
+ try
+ {
+ return getInstance(mechanism, provs[i]);
+ }
+ catch (NoSuchAlgorithmException nsae)
+ {
+ msg = nsae.getMessage();
+ }
+ }
+ throw new NoSuchAlgorithmException(msg);
+ }
+
+ public static final ExemptionMechanism getInstance(String mechanism,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ Provider p = Security.getProvider(provider);
+ if (p == null)
+ {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(mechanism, p);
+ }
+
+ public static final ExemptionMechanism getInstance(String mechanism,
+ Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ try
+ {
+ return new ExemptionMechanism((ExemptionMechanismSpi)
+ Engine.getInstance(SERVICE, mechanism, provider),
+ provider, mechanism);
+ }
+ catch (InvocationTargetException ite)
+ {
+ if (ite.getCause() instanceof NoSuchAlgorithmException)
+ throw (NoSuchAlgorithmException) ite.getCause();
+ else
+ throw new NoSuchAlgorithmException(mechanism);
+ }
+ catch (ClassCastException cce)
+ {
+ throw new NoSuchAlgorithmException(mechanism);
+ }
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ public final byte[] genExemptionBlob()
+ throws IllegalStateException, ExemptionMechanismException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ return emSpi.engineGenExemptionBlob();
+ }
+
+ public final int genExemptionBlob(byte[] output)
+ throws IllegalStateException, ExemptionMechanismException,
+ ShortBufferException
+ {
+ return genExemptionBlob(output, 0);
+ }
+
+ public final int genExemptionBlob(byte[] output, int outputOffset)
+ throws IllegalStateException, ExemptionMechanismException,
+ ShortBufferException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ return emSpi.engineGenExemptionBlob(output, outputOffset);
+ }
+
+ public final String getName()
+ {
+ return mechanism;
+ }
+
+ public final int getOutputSize(int inputLength) throws IllegalStateException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ return emSpi.engineGetOutputSize(inputLength);
+ }
+
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ public final void init(Key key)
+ throws ExemptionMechanismException, InvalidKeyException
+ {
+ emSpi.engineInit(key);
+ virgin = false;
+ }
+
+ public final void init(Key key, AlgorithmParameters params)
+ throws ExemptionMechanismException, InvalidAlgorithmParameterException,
+ InvalidKeyException
+ {
+ emSpi.engineInit(key, params);
+ virgin = false;
+ }
+
+ public final void init(Key key, AlgorithmParameterSpec params)
+ throws ExemptionMechanismException, InvalidAlgorithmParameterException,
+ InvalidKeyException
+ {
+ emSpi.engineInit(key, params);
+ virgin = false;
+ }
+
+ public final boolean isCryptoAllowed(Key key)
+ throws ExemptionMechanismException
+ {
+ return true;
+ }
+}
diff --git a/libjava/javax/crypto/ExemptionMechanismException.java b/libjava/javax/crypto/ExemptionMechanismException.java
new file mode 100644
index 00000000000..42e1c5e9b77
--- /dev/null
+++ b/libjava/javax/crypto/ExemptionMechanismException.java
@@ -0,0 +1,81 @@
+/* ExemptionMechanismException -- An error in an exemption mechanism.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License along
+with GNU Classpath; if not, write to the
+
+ Free Software Foundation, Inc.,
+ 59 Temple Place, Suite 330,
+ Boston, MA 02111-1307
+ USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under terms
+of your choice, provided that you also meet, for each linked independent
+module, the terms and conditions of the license of that module. An
+independent module is a module which is not derived from or based on
+this library. If you modify this library, you may extend this exception
+to your version of the library, but you are not obligated to do so. If
+you do not wish to do so, delete this exception statement from your
+version. */
+
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Signals a general exception in an {@link ExemptionMechanism}.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class ExemptionMechanismException extends GeneralSecurityException
+{
+
+ // Constant.
+ // ------------------------------------------------------------------------
+
+ /** Compatible with JDK1.4. */
+ private static final long serialVersionUID = 1572699429277957109L;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new exception with no detail message.
+ */
+ public ExemptionMechanismException()
+ {
+ super();
+ }
+
+ /**
+ * Create a new exception with a detail message.
+ *
+ * @param message The detail message.
+ */
+ public ExemptionMechanismException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/crypto/ExemptionMechanismSpi.java b/libjava/javax/crypto/ExemptionMechanismSpi.java
new file mode 100644
index 00000000000..78997ee0704
--- /dev/null
+++ b/libjava/javax/crypto/ExemptionMechanismSpi.java
@@ -0,0 +1,149 @@
+/* ExemptionMechanismSpi.java -- Exemption mechanism service provider interface.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The Service Provider Interface (SPI) for the {@link
+ * ExemptionMechanism} class.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public abstract class ExemptionMechanismSpi
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new exemption mechanism SPI.
+ */
+ public ExemptionMechanismSpi()
+ {
+ }
+
+ // Abstract instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Return a key blob for the key that this mechanism was initialized
+ * with.
+ *
+ * @return The key blob.
+ * @throws javax.crypto.ExemptionMechanismException If generating the
+ * blob fails.
+ */
+ protected abstract byte[] engineGenExemptionBlob()
+ throws ExemptionMechanismException;
+
+ /**
+ * Generate a key blob for the key that this mechanism was initialized
+ * with, storing it into the given byte array.
+ *
+ * @param output The destination for the key blob.
+ * @param outputOffset The index in the output array to start.
+ * @return The size of the key blob.
+ * @throws javax.crypto.ExemptionMechanismException If generating the
+ * blob fails.
+ * @throws javax.crypto.ShortBufferException If the output array is
+ * not large enough for the key blob.
+ */
+ protected abstract int engineGenExemptionBlob(byte[] output, int outputOffset)
+ throws ExemptionMechanismException, ShortBufferException;
+
+ /**
+ * Get the size of the output blob given an input key size. The actual
+ * blob may be shorter than the value returned by this method. Both
+ * values are in bytes.
+ *
+ * @param inputLength The input size.
+ * @return The output size.
+ */
+ protected abstract int engineGetOutputSize(int inputLength);
+
+ /**
+ * Initialize this mechanism with a key.
+ *
+ * @param key The key.
+ * @throws javax.crypto.ExemptionMechanismException If generating the
+ * blob fails.
+ * @throws java.security.InvalidKeyException If the supplied key
+ * cannot be used.
+ */
+ protected abstract void engineInit(Key key)
+ throws ExemptionMechanismException, InvalidKeyException;
+
+ /**
+ * Initialize this mechanism with a key and parameters.
+ *
+ * @param key The key.
+ * @param params The parameters.
+ * @throws javax.crypto.ExemptionMechanismException If generating the
+ * blob fails.
+ * @throws java.security.InvalidAlgorithmParameterExceptin If the
+ * supplied parameters are inappropriate.
+ * @throws java.security.InvalidKeyException If the supplied key
+ * cannot be used.
+ */
+ protected abstract void engineInit(Key key, AlgorithmParameters params)
+ throws ExemptionMechanismException, InvalidAlgorithmParameterException,
+ InvalidKeyException;
+
+ /**
+ * Initialize this mechanism with a key and parameters.
+ *
+ * @param key The key.
+ * @param params The parameters.
+ * @throws javax.crypto.ExemptionMechanismException If generating the
+ * blob fails.
+ * @throws java.security.InvalidAlgorithmParameterExceptin If the
+ * supplied parameters are inappropriate.
+ * @throws java.security.InvalidKeyException If the supplied key
+ * cannot be used.
+ */
+ protected abstract void engineInit(Key key, AlgorithmParameterSpec params)
+ throws ExemptionMechanismException, InvalidAlgorithmParameterException,
+ InvalidKeyException;
+}
diff --git a/libjava/javax/crypto/IllegalBlockSizeException.java b/libjava/javax/crypto/IllegalBlockSizeException.java
new file mode 100644
index 00000000000..1e442833c76
--- /dev/null
+++ b/libjava/javax/crypto/IllegalBlockSizeException.java
@@ -0,0 +1,71 @@
+/* IllegalBlockSizeException.java -- Signals illegal block sizes.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * This exception is thrown when finishing encryption without padding or
+ * decryption and the input is not a multiple of the cipher's block
+ * size.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class IllegalBlockSizeException extends GeneralSecurityException
+{
+
+ // Constant.
+ // ------------------------------------------------------------------------
+
+ /** Serialization constant. */
+ private static final long serialVersionUID = -1965144811953540392L;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ public IllegalBlockSizeException()
+ {
+ super();
+ }
+
+ public IllegalBlockSizeException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/crypto/KeyAgreement.java b/libjava/javax/crypto/KeyAgreement.java
new file mode 100644
index 00000000000..6f6ed34e04f
--- /dev/null
+++ b/libjava/javax/crypto/KeyAgreement.java
@@ -0,0 +1,373 @@
+/* KeyAgreement.java -- Engine for key agreement methods.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.lang.reflect.InvocationTargetException;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+
+import gnu.java.security.Engine;
+
+/**
+ * Key agreement is a method in which two or more parties may agree on a
+ * secret key for symmetric cryptography or message authentication
+ * without transmitting any secrets in the clear. Key agreement
+ * algorithms typically use a public/private key pair, and the
+ * public key (along with some additional information) is sent across
+ * untrusted networks.
+ *
+ * The most common form of key agreement used today is the
+ * Diffie-Hellman key exchange algorithm, described in PKCS #3 -
+ * Diffie Hellman Key Agreement Standard.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see KeyGenerator
+ * @see SecretKey
+ */
+public class KeyAgreement
+{
+
+ // Fields.
+ // ------------------------------------------------------------------------
+
+ private static final String SERVICE = "KeyAgreement";
+
+ /** The underlying key agreement implementation. */
+ private KeyAgreementSpi kaSpi;
+
+ /** The provider of this implementation. */
+ private Provider provider;
+
+ /** The name of this instance's algorithm. */
+ private String algorithm;
+
+ /** Singnals whether or not this instance has been initialized. */
+ private boolean virgin;
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ protected KeyAgreement(KeyAgreementSpi kaSpi, Provider provider,
+ String algorithm)
+ {
+ this.kaSpi = kaSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
+ virgin = true;
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get an implementation of an algorithm from the first provider that
+ * implements it.
+ *
+ * @param algorithm The name of the algorithm to get.
+ * @return The proper KeyAgreement instacne, if found.
+ * @throws java.security.NoSuchAlgorithmException If the specified
+ * algorithm is not implemented by any installed provider.
+ */
+ public static final KeyAgreement getInstance(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] provs = Security.getProviders();
+ String msg = algorithm;
+ for (int i = 0; i < provs.length; i++)
+ {
+ try
+ {
+ return getInstance(algorithm, provs[i]);
+ }
+ catch (NoSuchAlgorithmException nsae)
+ {
+ msg = nsae.getMessage();
+ }
+ }
+ throw new NoSuchAlgorithmException(msg);
+ }
+
+ /**
+ * Get an implementation of an algorithm from a named provider.
+ *
+ * @param algorithm The name of the algorithm to get.
+ * @param provider The name of the provider from which to get the
+ * implementation.
+ * @return The proper KeyAgreement instance, if found.
+ * @throws java.security.NoSuchAlgorithmException If the named provider
+ * does not implement the algorithm.
+ * @throws java.security.NoSuchProviderException If the named provider
+ * does not exist.
+ */
+ public static final KeyAgreement getInstance(String algorithm,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ Provider p = Security.getProvider(provider);
+ if (p == null)
+ {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(algorithm, p);
+ }
+
+ /**
+ * Get an implementation of an algorithm from a specific provider.
+ *
+ * @param algorithm The name of the algorithm to get.
+ * @param provider The provider from which to get the implementation.
+ * @return The proper KeyAgreement instance, if found.
+ * @throws java.security.NoSuchAlgorithmException If this provider
+ * does not implement the algorithm.
+ */
+ public static final KeyAgreement getInstance(String algorithm,
+ Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ try
+ {
+ return new KeyAgreement((KeyAgreementSpi)
+ Engine.getInstance(SERVICE, algorithm, provider),
+ provider, algorithm);
+ }
+ catch (InvocationTargetException ite)
+ {
+ if (ite.getCause() == null)
+ throw new NoSuchAlgorithmException(algorithm);
+ if (ite.getCause() instanceof NoSuchAlgorithmException)
+ throw (NoSuchAlgorithmException) ite.getCause();
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+ catch (ClassCastException cce)
+ {
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Do a phase in the key agreement. The number of times this method is
+ * called depends upon the algorithm and the number of parties
+ * involved, but must be called at least once with the
+ * Providers wishing to implement a key agreement algorithm must
+ * subclass this and provide an appropriate implementation for all the
+ * abstract methods below, and provide an appropriate entry in the
+ * master {@link java.security.Provider} class (the service name for key
+ * agreement algorithms is Providers wishing to implement a key generator must subclass this
+ * and provide an appropriate implementation for all the abstract
+ * methods below, and provide an appropriate entry in the master {@link
+ * java.security.Provider} class (the service name for key generators is
+ * The best way to describe a MAC is as a keyed one-way hash
+ * function, which looks like:
+ *
+ * where After this method succeeds, it may be used again as just after a
+ * call to After this method succeeds, it may be used again as just after a
+ * call to After this method succeeds, it may be used again as just after a
+ * call to Providers wishing to implement a Mac must subclass this class and
+ * provide appropriate implementations of all its abstract methods,
+ * then provide an entry pointing to this implementation in the master
+ * {@link java.security.Provider} class.
+ *
+ * Implemetations may optionally implement the {@link
+ * java.lang.Cloneable} interface.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public abstract class MacSpi
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new MacSpi instance.
+ */
+ public MacSpi()
+ {
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns a clone of this instance if cloning is supported.
+ *
+ * @return A clone of this instance.
+ * @throws java.lang.CloneNotSupportedException If this instance does
+ * not support cloneing.
+ */
+ public Object clone() throws CloneNotSupportedException
+ {
+ throw new CloneNotSupportedException();
+ }
+
+ // Abstract instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Finalize the computation of this MAC and return the result as a
+ * byte array.
+ *
+ * @return The MAC.
+ */
+ protected abstract byte[] engineDoFinal();
+
+ /**
+ * Return the total length, in bytes, of the computed MAC (the length
+ * of the byte array returned by {@link #doFinal()}.
+ *
+ * @return The MAC length.
+ */
+ protected abstract int engineGetMacLength();
+
+ /**
+ * Initialize (or re-initialize) this instance.
+ *
+ * @param key The key to use.
+ * @param params The parameters to use.
+ * @throws java.security.InvalidAlgorithmParameterException If this
+ * instance rejects the specified parameters.
+ * @throws java.security.InvalidKeyException If this instance rejects
+ * the specified key.
+ */
+ protected abstract void engineInit(Key key, AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException, InvalidKeyException;
+
+ /**
+ * Reset this instance. After this method succeeds, the state of this
+ * instance should be the same as it was before any data was input
+ * (possibly after a call to {@link
+ * #init(java.security.Key,java.security.spec.AlgorithmParameterSpec)},
+ * possibly not).
+ */
+ protected abstract void engineReset();
+
+ /**
+ * Update this MAC with a single byte.
+ *
+ * @param input The next byte.
+ */
+ protected abstract void engineUpdate(byte input);
+
+ /**
+ * Update this MAC with a portion of a byte array.
+ *
+ * @param input The next bytes.
+ * @param offset The index in When the sealed object is ready to be unsealed (and deserialized)
+ * the caller may use either
+ *
+ * This interface defines no new methods over {@link
+ * java.security.Key}, but rather is intended to be a marker
+ * interface and to provide type safety for secret keys. The format of secret keys should be Concrete implementations of this interface should override the
+ * {@link java.lang.Object#equals} and {@link java.lang.Object#hashCode}
+ * methods of {@link java.lang.Object} to use the actual key data rather
+ * than the identity-based default methods. Providers wishing to implement a secret key factory must
+ * subclass this and provide an appropriate implementation for all the
+ * abstract methods below, and provide an appropriate entry in the
+ * master {@link java.security.Provider} class (the service name for
+ * secret key factories is Implementations of Diffie-Hellman private keys should implement
+ * this interface. Applications that know a particular key is a
+ * Diffie-Hellman private key can safely cast it to this interface.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see DHKey
+ * @see DHPublicKey
+ */
+public interface DHPrivateKey extends DHKey, PrivateKey
+{
+
+ /** Compatible with JDK1.4. */
+ static final long serialVersionUID = 2211791113380396553L;
+
+ /**
+ * Returns the private value x.
+ *
+ * @return The private value x.
+ */
+ BigInteger getX();
+}
diff --git a/libjava/javax/crypto/interfaces/DHPublicKey.java b/libjava/javax/crypto/interfaces/DHPublicKey.java
new file mode 100644
index 00000000000..5e0b35bf008
--- /dev/null
+++ b/libjava/javax/crypto/interfaces/DHPublicKey.java
@@ -0,0 +1,69 @@
+/* DHPublicKey.java -- A Diffie-Hellman public key.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.interfaces;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+
+/**
+ * This interface marks a public key in the Diffie-Hellman key-exchange
+ * algorithm.
+ *
+ * Implementations of Diffie-Hellman public keys should implement
+ * this interface. Applications that know that a particular key is a
+ * Diffie-Hellman public key it can be safely cast to this interface.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see DHKey
+ * @see DHPrivateKey
+ */
+public interface DHPublicKey extends DHKey, PublicKey
+{
+
+ /** Compatible with JDK1.4. */
+ static final long serialVersionUID = -6628103563352519193L;
+
+ /**
+ * Get the public value y.
+ *
+ * @return The public value y.
+ */
+ BigInteger getY();
+}
diff --git a/libjava/javax/crypto/interfaces/PBEKey.java b/libjava/javax/crypto/interfaces/PBEKey.java
new file mode 100644
index 00000000000..53349189849
--- /dev/null
+++ b/libjava/javax/crypto/interfaces/PBEKey.java
@@ -0,0 +1,91 @@
+/* PBEKey.java -- A key derived from a password.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.interfaces;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Interface to a password-derived key for password-based encryption
+ * (PBE). Applications working with a {@link javax.crypto.SecretKey}
+ * that is known to be a password-based key can safely cast such keys to
+ * this interface.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public interface PBEKey extends SecretKey
+{
+
+ /** Compatible with JDK1.4. */
+ static final long serialVersionUID = -1430015993304333921L;
+
+ /**
+ * Retruns the iteration count, or 0 if not specified.
+ *
+ * @return The iteration count.
+ */
+ int getIterationCount();
+
+ /**
+ * Returns a copy of the password as a character array. It is the
+ * caller's responsibility to zero-out the password when it is no
+ * longer in use.
+ *
+ * Although it is not specified in the documentation,
+ * implementations should not copy or clone the password array, but
+ * rather return the reference to the array itself, so the caller has
+ * the ability to erase the password.
+ *
+ * @return The password.
+ */
+ char[] getPassword();
+
+ /**
+ * Returns a copy of the salt. It is the caller's responsibility to
+ * zero-out the salt when it is no longer in use.
+ *
+ * Although it is not specified in the documentation,
+ * implementations should not copy or clone the salt array, but
+ * rather return the reference to the array itself, so the caller has
+ * the ability to erase the salt.
+ *
+ * @return The salt.
+ */
+ byte[] getSalt();
+}
diff --git a/libjava/javax/crypto/spec/DESKeySpec.java b/libjava/javax/crypto/spec/DESKeySpec.java
new file mode 100644
index 00000000000..7423c969b63
--- /dev/null
+++ b/libjava/javax/crypto/spec/DESKeySpec.java
@@ -0,0 +1,220 @@
+/* DESKeySpec -- Keys for DES.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.InvalidKeyException;
+import java.security.spec.KeySpec;
+
+/**
+ * This class is a transparent wrapper for DES keys, which are arrays
+ * of 8 bytes.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class DESKeySpec implements KeySpec
+{
+
+ // Constants.
+ // ------------------------------------------------------------------------
+
+ /**
+ * The length of a DES key, in bytes.
+ */
+ public static final int DES_KEY_LEN = 8;
+
+ /**
+ * The key bytes.
+ */
+ private byte[] key;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new DES key spec, copying the first 8 bytes from the
+ * byte array.
+ *
+ * @param key The key bytes.
+ * @throws java.security.InvalidKeyException If there are less than 8
+ * bytes in the array.
+ */
+ public DESKeySpec(byte[] key) throws InvalidKeyException
+ {
+ this(key, 0);
+ }
+
+ /**
+ * Create a new DES key spec, starting at Each set of parameters consists of a base generator
+ * See PKCS
+ * #3 - Diffie-Hellman Key Agreement Standard for more information.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see javax.crypto.KeyAgreement
+ */
+public class DHParameterSpec implements AlgorithmParameterSpec
+{
+
+ // Variables.
+ // ------------------------------------------------------------------------
+
+ /** The base generator g. */
+ private BigInteger g;
+
+ /** The prime modulus p. */
+ private BigInteger p;
+
+ /** The length, in bits, of the private exponent. */
+ private int l;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new set of Diffie-Hellman parameters.
+ *
+ * @param p The prime modulus.
+ * @param g The base generator.
+ */
+ public DHParameterSpec(BigInteger p, BigInteger g)
+ {
+ this(p, g, 0);
+ }
+
+ /**
+ * Create a new set of Diffie-Hellman parameters.
+ *
+ * @param p The prime modulus.
+ * @param g The base generator.
+ * @param l The size of the private exponent, in bits.
+ */
+ public DHParameterSpec(BigInteger p, BigInteger g, int l)
+ {
+ this.p = p;
+ this.g = g;
+ this.l = l;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the base generator, g.
+ *
+ * @return The base generator g.
+ */
+ public BigInteger getG()
+ {
+ return g;
+ }
+
+ /**
+ * Get the length of the private exponent, in bits.
+ *
+ * @return The length of the private exponent, in bits, or 0 if this
+ * has not been explicitly set.
+ */
+ public int getL()
+ {
+ return l;
+ }
+
+ /**
+ * Get the prime modulus, p.
+ *
+ * @return The prime modulus, p.
+ */
+ public BigInteger getP()
+ {
+ return p;
+ }
+}
diff --git a/libjava/javax/crypto/spec/DHPrivateKeySpec.java b/libjava/javax/crypto/spec/DHPrivateKeySpec.java
new file mode 100644
index 00000000000..8a4a790a16c
--- /dev/null
+++ b/libjava/javax/crypto/spec/DHPrivateKeySpec.java
@@ -0,0 +1,115 @@
+/* DHPrivateKeySpec.java -- Wrapper for Diffie-Hellman private keys.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.math.BigInteger;
+import java.security.spec.KeySpec;
+
+/**
+ * A wrapper for Diffie-Hellman private key data.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see DHPublicKeySpec
+ */
+public class DHPrivateKeySpec implements KeySpec
+{
+
+ // Variables.
+ // ------------------------------------------------------------------------
+
+ /** The base generator. */
+ private BigInteger g;
+
+ /** The prime modulus. */
+ private BigInteger p;
+
+ /** The private exponent. */
+ private BigInteger x;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new Diffie-Hellman private key spec.
+ *
+ * @param x The private exponent.
+ * @param p The prime modulus.
+ * @param g The base generator.
+ */
+ public DHPrivateKeySpec(BigInteger x, BigInteger p, BigInteger g)
+ {
+ this.x = x;
+ this.p = p;
+ this.g = g;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the base generator.
+ *
+ * @return The base generator.
+ */
+ public BigInteger getG()
+ {
+ return g;
+ }
+
+ /**
+ * Get the prime modulus.
+ *
+ * @return The prime modulus.
+ */
+ public BigInteger getP()
+ {
+ return p;
+ }
+
+ /**
+ * Get the private exponent.
+ *
+ * @return The private exponent.
+ */
+ public BigInteger getX()
+ {
+ return x;
+ }
+}
diff --git a/libjava/javax/crypto/spec/DHPublicKeySpec.java b/libjava/javax/crypto/spec/DHPublicKeySpec.java
new file mode 100644
index 00000000000..723dfefa404
--- /dev/null
+++ b/libjava/javax/crypto/spec/DHPublicKeySpec.java
@@ -0,0 +1,115 @@
+/* DHPublicKeySpec.java -- Wrapper for Diffie-Hellman public keys.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.math.BigInteger;
+import java.security.spec.KeySpec;
+
+/**
+ * A wrapper for Diffie-Hellman public key data.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see DHPrivateKeySpec
+ */
+public class DHPublicKeySpec implements KeySpec
+{
+
+ // Variables.
+ // ------------------------------------------------------------------------
+
+ /** The base generator. */
+ private BigInteger g;
+
+ /** The prime modulus. */
+ private BigInteger p;
+
+ /** The public value. */
+ private BigInteger y;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new Diffie-Hellman public key spec.
+ *
+ * @param y The public value.
+ * @param p The prime modulus.
+ * @param g The base generator.
+ */
+ public DHPublicKeySpec(BigInteger y, BigInteger p, BigInteger g)
+ {
+ this.y = y;
+ this.p = p;
+ this.g = g;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the base generator.
+ *
+ * @return The base generator.
+ */
+ public BigInteger getG()
+ {
+ return g;
+ }
+
+ /**
+ * Get the prime modulus.
+ *
+ * @return The prime modulus.
+ */
+ public BigInteger getP()
+ {
+ return p;
+ }
+
+ /**
+ * Get the public value.
+ *
+ * @return The public value.
+ */
+ public BigInteger getY()
+ {
+ return y;
+ }
+}
diff --git a/libjava/javax/crypto/spec/IvParameterSpec.java b/libjava/javax/crypto/spec/IvParameterSpec.java
new file mode 100644
index 00000000000..1c09c76659f
--- /dev/null
+++ b/libjava/javax/crypto/spec/IvParameterSpec.java
@@ -0,0 +1,96 @@
+/* IvParameterSpec.java -- A simple wrapper for initialization vectors.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * A wrapper for an initialization vector. An initialization vector is
+ * necessary for any cipher in any feedback mode, e.g. CBC.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class IvParameterSpec implements AlgorithmParameterSpec
+{
+
+ // Fields.
+ // ------------------------------------------------------------------------
+
+ /** The IV. */
+ private byte[] iv;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new initialization vector spec from an entire byte array.
+ *
+ * @param iv The IV bytes.
+ */
+ public IvParameterSpec(byte[] iv)
+ {
+ this(iv, 0, iv.length);
+ }
+
+ /**
+ * Create a new initialization vector spec from part of a byte array.
+ *
+ * @param iv The IV bytes.
+ * @param off The offset into the IV bytes.
+ * @param len The number of IV bytes.
+ */
+ public IvParameterSpec(byte[] iv, int off, int len)
+ {
+ this.iv = new byte[len];
+ System.arraycopy(iv, off, this.iv, 0, len);
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the IV. This method does not copy the byte array.
+ *
+ * @return The IV.
+ */
+ public byte[] getIV()
+ {
+ return iv;
+ }
+}
diff --git a/libjava/javax/crypto/spec/PBEKeySpec.java b/libjava/javax/crypto/spec/PBEKeySpec.java
new file mode 100644
index 00000000000..7a8c224cc64
--- /dev/null
+++ b/libjava/javax/crypto/spec/PBEKeySpec.java
@@ -0,0 +1,176 @@
+/* PBEKeySpec.java -- Wrapper for password-based keys.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.spec.KeySpec;
+
+/**
+ * A wrapper for a password-based key, used for password-based
+ * encryption (PBE).
+ *
+ * Examples of password-based encryption algorithms include:
+ *
+ * Since this class implements {@link javax.crypto.SecretKey}, which
+ * in turn extends {@link java.security.Key}, so instances of this class
+ * may be passed directly to the This class may be used in the same way as {@link
+ * HttpURLConnection}, and it will transparently negotiate the SSL
+ * connection.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public abstract class HttpsURLConnection extends HttpURLConnection
+{
+
+ // Fields.
+ // ------------------------------------------------------------------
+
+ /** The default verifier. */
+ private static HostnameVerifier defaultVerifier;
+
+ /** The default factory. */
+ private static SSLSocketFactory defaultFactory;
+
+ /**
+ * The hostname verifier used for this connection.
+ */
+ protected HostnameVerifier hostnameVerifier;
+
+ /**
+ * This connection's socket factory.
+ */
+ private SSLSocketFactory factory;
+
+ // Static initializer.
+ // ------------------------------------------------------------------
+
+ static {
+ defaultVerifier = new TrivialHostnameVerifier();
+ try
+ {
+ defaultFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
+ }
+
+ // Constructor.
+ // ------------------------------------------------------------------
+
+ /**
+ * Creates a new HTTPS URL connection.
+ *
+ * @param url The URL of the connection being established.
+ * @throws IOException If the connection cannot be established.
+ */
+ protected HttpsURLConnection(URL url) throws IOException
+ {
+ super(url);
+ hostnameVerifier = defaultVerifier;
+ factory = defaultFactory;
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------
+
+ /**
+ * Returns the default hostname verifier used in all new
+ * connections.
+ *
+ * @return The default hostname verifier.
+ */
+ public static HostnameVerifier getDefaultHostnameVerifier()
+ {
+ return defaultVerifier;
+ }
+
+ /**
+ * Sets the default hostname verifier to be used in all new
+ * connections.
+ *
+ * @param newDefault The new default hostname verifier.
+ * @throws IllegalArgumentException If newDefault is null.
+ * @throws SecurityException If there is a security manager
+ * currently installed and the caller does not have the {@link
+ * SSLPermission} "setHostnameVerifier".
+ */
+ public static void setDefaultHostnameVerifier(HostnameVerifier newDefault)
+ {
+ if (newDefault == null)
+ throw new IllegalArgumentException("default verifier cannot be null");
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new SSLPermission("setHostnameVerifier"));
+ defaultVerifier = newDefault;
+ }
+
+ /**
+ * Returns the default SSL socket factory used in all new
+ * connections.
+ *
+ * @return The default SSL socket factory.
+ */
+ public static SSLSocketFactory getDefaultSSLSocketFactory()
+ {
+ return defaultFactory;
+ }
+
+ /**
+ * Sets the default SSL socket factory to be used in all new
+ * connections.
+ *
+ * @param newDefault The new socket factory.
+ * @throws IllegalArgumentException If newDefault is null.
+ * @throws SecurityException If there is a security manager
+ * installed and a call to {@link
+ * SecurityManager#checkSetFactory()} fails.
+ */
+ public static void setDefaultSSLSocketFactory(SSLSocketFactory newDefault)
+ {
+ if (newDefault == null)
+ throw new IllegalArgumentException("default factory cannot be null");
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkSetFactory();
+ defaultFactory = newDefault;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------
+
+ /**
+ * Returns the current hostname verifier for this instance.
+ *
+ * @return The hostname verifier.
+ */
+ public HostnameVerifier getHostnameVerifier()
+ {
+ return hostnameVerifier;
+ }
+
+ /**
+ * Sets the hostname verifier for this instance.
+ *
+ * @param hostnameVerifier The new verifier.
+ * @throws IllegalArgumentException If hostnameVerifier is
+ * null.
+ */
+ public void setHostnameVerifier(HostnameVerifier hostnameVerifier)
+ {
+ if (hostnameVerifier == null)
+ throw new IllegalArgumentException("verifier cannot be null");
+ this.hostnameVerifier = hostnameVerifier;
+ }
+
+ /**
+ * Returns the current SSL socket factory for this instance.
+ *
+ * @return The current SSL socket factory.
+ */
+ public SSLSocketFactory getSSLSocketFactory()
+ {
+ return factory;
+ }
+
+ /**
+ * Sets the SSL socket factory for this instance.
+ *
+ * @param factory The new factory.
+ * @throws IllegalArgumentException If factory is null.
+ */
+ public void setSSLSocketFactory(SSLSocketFactory factory)
+ {
+ if (factory == null)
+ throw new IllegalArgumentException("factory cannot be null");
+ this.factory = factory;
+ }
+
+ // Abstract methods.
+ // -------------------------------------------------------------------
+
+ /**
+ * Returns the cipher name negotiated for this connection.
+ *
+ * @return The cipher name.
+ * @throws IllegalStateException If the connection has not yet been
+ * established.
+ */
+ public abstract String getCipherSuite();
+
+ /**
+ * Returns the certificates used on the local side in this
+ * connection.
+ *
+ * @return The local certificates.
+ * @throws IllegalStateException If the connection has not yet been
+ * established.
+ */
+ public abstract Certificate[] getLocalCertificates();
+
+ /**
+ * Returns the certificates sent by the other party.
+ *
+ * @return The peer's certificates.
+ * @throws IllegalStateException If the connection has not yet been
+ * established.
+ * @throws SSLPeerUnverifiedException If the peer could not be
+ * verified.
+ */
+ public abstract Certificate[] getServerCertificates() throws SSLPeerUnverifiedException;
+}
diff --git a/libjava/javax/net/ssl/KeyManager.java b/libjava/javax/net/ssl/KeyManager.java
new file mode 100644
index 00000000000..083f3f592ed
--- /dev/null
+++ b/libjava/javax/net/ssl/KeyManager.java
@@ -0,0 +1,51 @@
+/* KeyManager.java -- marker interface for key manager classes.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+/**
+ * A marker interface for objects that serve as key managers in SSL
+ * communications. Key managers typically keep track of the public
+ * certificates and private keys when authenticating the local host to
+ * remote host, and thus is typically used in SSL servers.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public interface KeyManager
+{
+}
diff --git a/libjava/javax/net/ssl/KeyManagerFactory.java b/libjava/javax/net/ssl/KeyManagerFactory.java
new file mode 100644
index 00000000000..a166f60aa43
--- /dev/null
+++ b/libjava/javax/net/ssl/KeyManagerFactory.java
@@ -0,0 +1,281 @@
+/* KeyManagerFactory.java -- factory for key managers.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.lang.reflect.InvocationTargetException;
+
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+
+import gnu.java.security.Engine;
+
+/**
+ * A class that creates key manager implementations based on a
+ * requested algorithm.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public class KeyManagerFactory
+{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------
+
+ /** The service name for key manager factories. */
+ private static final String KEY_MANAGER_FACTORY = "KeyManagerFactory";
+
+ /** The system default trust manager algorithm. */
+ private static final String DEFAULT_ALGORITHM = "JessieX509";
+
+ /** The underlying engine. */
+ private final KeyManagerFactorySpi kmfSpi;
+
+ /** The provider of this implementation. */
+ private final Provider provider;
+
+ /** The name of this algorithm. */
+ private final String algorithm;
+
+ // Constructor.
+ // ------------------------------------------------------------------
+
+ /**
+ * Create a new key manager factory.
+ *
+ * @param kmfSpi The underlying engine.
+ * @param provider The engine's provider.
+ * @param algorithm The name of this algorithm.
+ */
+ protected KeyManagerFactory(KeyManagerFactorySpi kmfSpi,
+ Provider provider, String algorithm)
+ {
+ this.kmfSpi = kmfSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------
+
+ /**
+ * Get the default algorithm name. This value may be specified at
+ * run-time via the security property
+ * "ssl.KeyManagerFactory.algorithm". If this property is
+ * not specified, this method returns "JessieX509".
+ *
+ * @return The default key manager factory algorithm's name.
+ */
+ public static final String getDefaultAlgorithm()
+ {
+ String alg = null;
+ try
+ {
+ alg = (String) AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return Security.getProperty("ssl.KeyManagerFactory.algorithm");
+ }
+ }
+ );
+ }
+ catch (SecurityException se)
+ {
+ }
+ if (alg == null)
+ alg = DEFAULT_ALGORITHM;
+ return alg;
+ }
+
+ /**
+ * Get an instance of the named key manager factory, from the first
+ * provider that implements it.
+ *
+ * @param algorithm The type of key manager factory to get.
+ * @return An appropriate implementation of that algoritm.
+ * @throws NoSuchAlgorithmException If no provider implements the
+ * requested algorithm.
+ */
+ public static final KeyManagerFactory getInstance(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] provs = Security.getProviders();
+ for (int i = 0; i < provs.length; i++)
+ {
+ try
+ {
+ return getInstance(algorithm, provs[i]);
+ }
+ catch (NoSuchAlgorithmException ignore)
+ {
+ }
+ }
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+
+ /**
+ * Get an instance of the named key manager factory, from the named
+ * provider.
+ *
+ * @param algorithm The type of key manager factory to get.
+ * @param provider The name of the provider to get the
+ * implementation from.
+ * @return An appropriate implementation of that algorithm.
+ * @throws NoSuchAlgorithmException If the provider does not
+ * implement the requested algorithm.
+ * @throws NoSuchProviderException If the named provider does not
+ * exist.
+ */
+ public static final KeyManagerFactory getInstance(String algorithm, String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (provider == null)
+ throw new IllegalArgumentException("provider is null");
+ Provider p = Security.getProvider(provider);
+ if (p == null)
+ throw new NoSuchProviderException(provider);
+ return getInstance(algorithm, p);
+ }
+
+ /**
+ * Get an instance of the named key manager factory, from the given
+ * provider.
+ *
+ * @param algorithm The type of key manager factory to get.
+ * @param provider The provider to get the implementation from.
+ * @return An appropriate implementation of that algorithm.
+ * @throws NoSuchAlgorithmException If the provider does not
+ * implement the requested algorithm.
+ * @throws IllegalArgumentException If provider is null.
+ */
+ public static final KeyManagerFactory getInstance(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ if (provider == null)
+ throw new IllegalArgumentException("provider is null");
+ try
+ {
+ return new KeyManagerFactory((KeyManagerFactorySpi)
+ Engine.getInstance(KEY_MANAGER_FACTORY, algorithm, provider),
+ provider, algorithm);
+ }
+ catch (InvocationTargetException ite)
+ {
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+ catch (ClassCastException cce)
+ {
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------
+
+ /**
+ * Returns the name of this key manager factory algorithm.
+ *
+ * @return The name of this key manager factory algorithm.
+ */
+ public final String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * Get an array of key managers appropriate for this algorithm, with
+ * the most preferred manager first.
+ *
+ * @return The array of key managers.
+ */
+ public final KeyManager[] getKeyManagers()
+ {
+ return kmfSpi.engineGetKeyManagers();
+ }
+
+ /**
+ * Returns the provider of this implementation.
+ *
+ * @return The provider of this implementation.
+ */
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Initialize this instance with an implementation-dependent
+ * parameter object.
+ *
+ * @param params The parameters to initialize with.
+ * @throws InvalidAlgorithmParameterException If the specified
+ * parameters are inappropriate.
+ */
+ public final void init(ManagerFactoryParameters params)
+ throws InvalidAlgorithmParameterException
+ {
+ kmfSpi.engineInit(params);
+ }
+
+ /**
+ * Initialize this instance with a key store and a password for
+ * private key entries.
+ *
+ * @param store The key store to read.
+ * @param passwd The password protecting private keys in the store.
+ * @throws KeyStoreException If an error occurs reading the keys.
+ * @throws NoSuchAlgorithmException If an algorithm (such as a
+ * certificate algorithm) is not available.
+ * @throws UnrecoverableKeyException If the password is incorrect.
+ */
+ public final void init(KeyStore store, char[] passwd)
+ throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ kmfSpi.engineInit(store, passwd);
+ }
+}
diff --git a/libjava/javax/net/ssl/KeyManagerFactorySpi.java b/libjava/javax/net/ssl/KeyManagerFactorySpi.java
new file mode 100644
index 00000000000..3ed978f356c
--- /dev/null
+++ b/libjava/javax/net/ssl/KeyManagerFactorySpi.java
@@ -0,0 +1,102 @@
+/* KeyManagerFactorySpi.java -- SPI for key manager factories.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+
+/**
+ * The Service Provider Interface (SPI) for key manager
+ * factories.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public abstract class KeyManagerFactorySpi
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------
+
+ public KeyManagerFactorySpi()
+ {
+ super();
+ }
+
+ // Abstract methods.
+ // ------------------------------------------------------------------
+
+ /**
+ * Engine method for retrieving this factory's key managers.
+ *
+ * @return The key managers.
+ */
+ protected abstract KeyManager[] engineGetKeyManagers();
+
+ /**
+ * Engine method for initializing this factory with some
+ * algorithm-specific parameters.
+ *
+ * @param params The factory parameters.
+ * @throws InvalidAlgorithmParameterException If the supplied parameters
+ * are inappropriate for this instance.
+ */
+ protected abstract void engineInit(ManagerFactoryParameters params)
+ throws InvalidAlgorithmParameterException;
+
+ /**
+ * Engine method for initializing this factory with a key store and a
+ * password for private keys. Either parameter may be To control the class that gets returned by this method, set the
+ * security property "ssl.ServerSocketFactory.provider" to the class
+ * name of a concrete implementation of this class. If not set, a
+ * system-dependent implementation will be used. The implementation returned is created by the first implementation
+ * of the {@link SSLContext} class found, which is initialized with
+ * default parameters. To control the key and trust manager factory
+ * algorithms used as defaults, set the security properties
+ * "ssl.keyManagerFactory.algorithm" and "ssl.trustManagerFactory.algorithm"
+ * to the appropriate names. Using this method is not recommended. Instead, use the methods of
+ * {@link SSLContext}, which provide much better control over the
+ * creation of server socket factories. The handshake will begin implicitly when any attempt to read or
+ * write to the socket is made. To control the class that gets returned by this method, set the
+ * security property "ssl.SocketFactory.provider" to the class
+ * name of a concrete implementation of this class. If not set, a
+ * system-dependent implementation will be used. The implementation returned is created by the first implementation
+ * of the {@link SSLContext} class found, which is initialized with
+ * default parameters. To control the key and trust manager factory
+ * algorithms used as defaults, set the security properties
+ * "ssl.keyManagerFactory.algorithm" and "ssl.trustManagerFactory.algorithm"
+ * to the appropriate names. Using this method is not recommended. Instead, use the methods of
+ * {@link SSLContext}, which provide much better control over the
+ * creation of socket factories. A permission controlling access to authentication service. The
+ * actions field of auth permission objects is ignored; the whole
+ * of the permission is defined by the target. The authentication permission targets recognized are: Allows access to the {@link
+ * Subject#doAs(javax.security.auth.Subject java.security.PrivilegedAction)}
+ * methods. Allows access to the {@link
+ * Subject#doAsPrivileged(javax.security.auth.Subject,
+ * java.security.PrivilegedAction, java.security.AccessControlContext)}
+ * methods. Allows access to the {@link Subject} associated with a
+ * thread. Allows access to the {@link Subject} associated with a
+ * {@link SubjectDomainCombiner}. Allows a {@link Subject} to be marked as read-only. Allows the set of principals of a subject to be modified. Allows the set of public credentials of a subject to be
+ * modified. Allows the set of private credentials of a subject to be
+ * modified. Allows a {@link Refreshable} credential to be refreshed. Allows a {@link Destroyable} credential to be destroyed. Allows a {@link javax.security.auth.login.LoginContext} for the
+ * given name. name can also be a wildcard ( Allows the system-wide login {@link
+ * javax.security.auth.login.Configuration} to be retrieved. Allows the system-wide login {@link
+ * javax.security.auth.login.Configuration} to be set. Allows the system-wide login {@link
+ * javax.security.auth.login.Configuration} to be refreshed. The target of this permission is formatted as follows: CredentialClassName is either the name of a private credential
+ * class name, or a wildcard character ( Each element of the returned array is a pair; the first element is the
+ * principal class name, and the second is the principal name.
+ *
+ * @return The principal list.
+ */
+ public String[][] getPrincipals()
+ {
+ String[][] ret = new String[principals.size()][];
+ Iterator it = principals.iterator();
+ for (int i = 0; i < principals.size() && it.hasNext(); i++)
+ {
+ CredOwner co = (CredOwner) it.next();
+ ret[i] = new String[] { co.getPrincipalClass(), co.getPrincipalName() };
+ }
+ return ret;
+ }
+
+ public int hashCode()
+ {
+ return credentialClass.hashCode() + principals.hashCode();
+ }
+
+ /**
+ * Test if this permission implies another. This method returns true if:
+ *
+ * Returns the subject associated with the given {@link
+ * AccessControlContext}. All this method does is retrieve the Subject object from the supplied
+ * context's {@link DomainCombiner}, if any, and if it is an instance of
+ * a {@link SubjectDomainCombiner}.
+ *
+ * @param context The context to retrieve the subject from.
+ * @return The subject assoctiated with the context, or Run a method as another subject. This method will obtain the current
+ * {@link AccessControlContext} for this thread, then creates another with
+ * a {@link SubjectDomainCombiner} with the given subject. The supplied
+ * action will then be run with the modified context. Run a method as another subject. This method will obtain the current
+ * {@link AccessControlContext} for this thread, then creates another with
+ * a {@link SubjectDomainCombiner} with the given subject. The supplied
+ * action will then be run with the modified context. Run a method as another subject. This method will create a new
+ * {@link AccessControlContext} derived from the given one, with a
+ * {@link SubjectDomainCombiner} with the given subject. The supplied
+ * action will then be run with the modified context. Run a method as another subject. This method will create a new
+ * {@link AccessControlContext} derived from the given one, with a
+ * {@link SubjectDomainCombiner} with the given subject. The supplied
+ * action will then be run with the modified context. Returns whether or not this subject is read-only. Marks this subject as read-only. Implementations of this interface are passed to a {@link CallbackHandler},
+ * allowing underlying security services the ability to interact with a calling
+ * application to retrieve specific authentication data such as usernames and
+ * passwords, or to display certain information, such as error and warning
+ * messages. An application implements a Underlying security services make requests for different types of
+ * information by passing individual Callbacks to the A default If the security property is set to the fully qualified name of a
+ * All default handler implementations must provide a public zero-argument
+ * constructor. Retrieve or display the information requested in the provided
+ * {@link Callback}s. The Unspecified option type. The YES/NO confirmation option. An underlying security service specifies this as the YES/NO/CANCEL confirmation confirmation option. An underlying security service specifies this as the OK/CANCEL confirmation confirmation option. An underlying security service specifies this as the YES option. If an NO option. If an CANCEL option. If an OK option. If an Construct a Underlying security services use this constructor if they require
+ * either a YES/NO, YES/NO/CANCEL or OK/CANCEL confirmation. Construct a Underlying security services use this constructor if they require a
+ * confirmation different from the available preset confirmations provided
+ * (for example, CONTINUE/ABORT or STOP/GO). The confirmation options are
+ * listed in the Construct a Underlying security services use this constructor if they require
+ * either a YES/NO, YES/NO/CANCEL or OK/CANCEL confirmation. Construct a Underlying security services use this constructor if they require a
+ * confirmation different from the available preset confirmations provided
+ * (for example, CONTINUE/ABORT or STOP/GO). The confirmation options are
+ * listed in the Get the option type. If this method returns {@link #UNSPECIFIED_OPTION}, then this
+ * Set the retrieved password. This method makes a copy of the input password before storing it. Get the retrieved password. This method returns a copy of the retrieved password. Underlying security services instantiate and pass a
+ * Construct a Returns the message's Returns the The base class for public-key certificates. This class is deprecated in favor of the {@link
+ * java.security.cert.Certificate} class. It should not be used in new
+ * applications. Tests if this certificate equals another. Computes a hash code for this certificate. Return the encoded form of this certificate. Verifies the signature of this certificate. Verifies the signature of this certificate, using the specified security
+ * provider. Returns a printable representation of this certificate. Returns this certificate's public key. Signals a problem when encoding certificates. This class is deprecated in favor of the {@link
+ * java.security.cert.CertificateEncodingException} class. It should not be used
+ * in new applications. Signals a generic problem with certificates. This class is deprecated in favor of the {@link
+ * java.security.cert.CertificateException} class. It should not be used in new
+ * applications. Signals that a certificate has expired. This class is deprecated in favor of the {@link
+ * java.security.cert.CertificateExpiredException} class. It should not be used
+ * in new applications. Signals that a certificate is not yet valid. This class is deprecated in favor of the {@link
+ * java.security.cert.CertificateNotYetValidException} class. It should not be
+ * used in new applications. Signals a parsing error when decoding a certificate. This class is deprecated. It should not be used in new
+ * applications. An implementation of the {@link X509Certificate} class that delegates
+ * calls to a {@link java.security.cert.X509Certificate}. The base class of all X.509 certificates. This class is deprecated in favor of the {@link
+ * java.security.cert.X509Certificate} class. It should not be used in new
+ * applications. Get an instance of X509Certificate for the given encoded bytes. Get an instance of X509Certificate for the given encoded stream. Check if this certificate is valid now. Check if this certificate is valid for the given date. Returns the X.509 version number. Returns this certificate's serial number. Returns the distinguished name of this certificate's issuer. Returns the distinguished name of this certificate's subject. Returns the not before portion of this certificate's validity
+ * period. Returns the not after portion of this certificate's validity
+ * period. Returns the name of this certificate's signature algorithm. Returns the object identifier (OID) of this certificate's signature
+ * algorithm. The returned string is a sequence of integers separated by
+ * periods. Returns the signature parameters. The returned byte array contains the
+ * raw DER-encoded parameters. This exception is thrown by a SASL mechanism implementation to indicate
+ * that the SASL exchange has failed due to reasons related to authentication,
+ * such as an invalid identity, passphrase, or key. Note that the lack of an A static class for creating SASL clients and servers. This class defines the policy of how to locate, load, and instantiate SASL
+ * clients and servers. For example, an application or library gets a SASL client instance by
+ * doing something like: It can then proceed to use the instance to create an authenticated
+ * connection. Similarly, a server gets a SASL server instance by using code that looks
+ * as follows: The name of a property that specifies the quality-of-protection to use.
+ * The property contains a comma-separated, ordered list of quality-of-
+ * protection values that the client or server is willing to support. A qop
+ * value is one of: The order of the list specifies the preference order of the client or
+ * server. If this property is absent, the default qop is The value of this constant is The name of a property that specifies the cipher strength to use. The
+ * property contains a comma-separated, ordered list of cipher strength
+ * values that the client or server is willing to support. A strength value
+ * is one of: The order of the list specifies the preference order of the client or
+ * server. An implementation should allow configuration of the meaning of
+ * these values. An application may use the Java Cryptography Extension (JCE)
+ * with JCE-aware mechanisms to control the selection of cipher suites that
+ * match the strength values. If this property is absent, the default strength is
+ * The value of this constant is The name of a property that specifies whether the server must authenticate
+ * to the client. The property contains The value of this constant is
+ * The name of a property that specifies the maximum size of the receive
+ * buffer in bytes of {@link SaslClient}/{@link SaslServer}. The property
+ * contains the string representation of an integer. If this property is absent, the default size is defined by the
+ * mechanism. The value of this constant is The name of a property that specifies the maximum size of the raw send
+ * buffer in bytes of {@link SaslClient}/{@link SaslServer}. The property
+ * contains the string representation of an integer. The value of this
+ * property is negotiated between the client and server during the
+ * authentication exchange. The value of this constant is The name of a property that specifies whether mechanisms susceptible
+ * to simple plain passive attacks (e.g., "PLAIN") are not permitted. The
+ * property contains The value of this constant is The name of a property that specifies whether mechanisms susceptible to
+ * active (non-dictionary) attacks are not permitted. The property contains
+ * The value of this constant is The name of a property that specifies whether mechanisms susceptible to
+ * passive dictionary attacks are not permitted. The property contains
+ * The value of this constant is The name of a property that specifies whether mechanisms that accept
+ * anonymous login are not permitted. The property contains The value of this constant is The value of this constant is null to clear this
+ * value. CRLs matched by this selector must have an issuer name in this
+ * set.
+ *
+ * @param names The issuer names.
+ * @throws IOException If any of the elements in the collection is not
+ * a valid name.
+ */
+ public void setIssuerNames(Collection names) throws IOException
+ {
+ if (names == null)
+ {
+ issuerNames = null;
+ return;
+ }
+ List l = new ArrayList(names.size());
+ for (Iterator it = names.iterator(); it.hasNext(); )
+ {
+ Object o = it.next();
+ if (o instanceof X500Principal)
+ l.add(o);
+ else if (o instanceof String)
+ {
+ try
+ {
+ l.add(new X500Principal((String) o));
+ }
+ catch (IllegalArgumentException iae)
+ {
+ IOException ioe = new IOException("malformed name: " + o);
+ ioe.initCause(iae);
+ throw ioe;
+ }
+ }
+ else if (o instanceof byte[])
+ {
+ try
+ {
+ l.add(new X500Principal((byte[]) o));
+ }
+ catch (IllegalArgumentException iae)
+ {
+ IOException ioe = new IOException("malformed name");
+ ioe.initCause(iae);
+ throw ioe;
+ }
+ }
+ else if (o instanceof InputStream)
+ {
+ try
+ {
+ l.add(new X500Principal((InputStream) o));
+ }
+ catch (IllegalArgumentException iae)
+ {
+ IOException ioe = new IOException("malformed name");
+ ioe.initCause(iae);
+ throw ioe;
+ }
+ }
+ else
+ throw new IOException("not a valid name: " +
+ (o != null ? o.getClass().getName() : "null"));
+
+ }
+ issuerNames = l;
+ }
+
+ /**
+ * Returns the set of issuer names that are matched by this selector,
+ * or null if this criteria is not set. The returned
+ * collection is not modifiable.
+ *
+ * @return The set of issuer names.
+ */
+ public Collection getIssuerNames()
+ {
+ if (issuerNames != null)
+ return Collections.unmodifiableList(issuerNames);
+ else
+ return null;
+ }
+
+ /**
+ * Returns the maximum value of the CRLNumber extension present in
+ * CRLs matched by this selector, or null if this
+ * criteria is not set.
+ *
+ * @return The maximum CRL number.
+ */
+ public BigInteger getMaxCRL()
+ {
+ return maxCrlNumber;
+ }
+
+ /**
+ * Returns the minimum value of the CRLNumber extension present in
+ * CRLs matched by this selector, or null if this
+ * criteria is not set.
+ *
+ * @return The minimum CRL number.
+ */
+ public BigInteger getMinCRL()
+ {
+ return minCrlNumber;
+ }
+
+ /**
+ * Sets the maximum value of the CRLNumber extension present in CRLs
+ * matched by this selector. Specify null to clear this
+ * criterion.
+ *
+ * @param maxCrlNumber The maximum CRL number.
+ */
+ public void setMaxCRLNumber(BigInteger maxCrlNumber)
+ {
+ this.maxCrlNumber = maxCrlNumber;
+ }
+
+ /**
+ * Sets the minimum value of the CRLNumber extension present in CRLs
+ * matched by this selector. Specify null to clear this
+ * criterion.
+ *
+ * @param minCrlNumber The minimum CRL number.
+ */
+ public void setMinCRLNumber(BigInteger minCrlNumber)
+ {
+ this.minCrlNumber = minCrlNumber;
+ }
+
+ /**
+ * Returns the date when this CRL must be valid; that is, the date
+ * must be after the thisUpdate date, but before the nextUpdate date.
+ * Returns null if this criterion is not set.
+ *
+ * @return The date.
+ */
+ public Date getDateAndTime()
+ {
+ return date != null ? (Date) date.clone() : null;
+ }
+
+ /**
+ * Sets the date at which this CRL must be valid. Specify
+ * null to clear this criterion.
+ *
+ * @param date The date.
+ */
+ public void setDateAndTime(Date date)
+ {
+ this.date = date != null ? (Date) date.clone() : null;
+ }
+
+ /**
+ * Returns the certificate being checked, or null if this
+ * value is not set.
+ *
+ * @return The certificate.
+ */
+ public X509Certificate getCertificateChecking()
+ {
+ return cert;
+ }
+
+ /**
+ * Sets the certificate being checked. This is not a criterion, but
+ * info used by certificate store implementations to aid in searching.
+ *
+ * @param cert The certificate.
+ */
+ public void setCertificateChecking(X509Certificate cert)
+ {
+ this.cert = cert;
+ }
+
+ /**
+ * Returns a string representation of this selector. The string will
+ * only describe the enabled criteria, so if none are enabled this will
+ * return a string that contains little else besides the class name.
+ *
+ * @return The string.
+ */
+ public String toString()
+ {
+ StringBuffer str = new StringBuffer(X509CRLSelector.class.getName());
+ GetPropertyAction getProp = new GetPropertyAction("line.separator");
+ String nl = (String) AccessController.doPrivileged(getProp);
+ String eol = ";" + nl;
+
+ str.append(" {").append(nl);
+ if (issuerNames != null)
+ str.append(" issuer names = ").append(issuerNames).append(eol);
+ if (maxCrlNumber != null)
+ str.append(" max CRL = ").append(maxCrlNumber).append(eol);
+ if (minCrlNumber != null)
+ str.append(" min CRL = ").append(minCrlNumber).append(eol);
+ if (date != null)
+ str.append(" date = ").append(date).append(eol);
+ if (cert != null)
+ str.append(" certificate = ").append(cert).append(eol);
+ str.append("}").append(nl);
+ return str.toString();
+ }
+
+ /**
+ * Checks a CRL against the criteria of this selector, returning
+ * true if the given CRL matches all the criteria.
+ *
+ * @param _crl The CRL being checked.
+ * @return True if the CRL matches, false otherwise.
+ */
+ public boolean match(CRL _crl)
+ {
+ if (!(_crl instanceof X509CRL))
+ return false;
+ X509CRL crl = (X509CRL) _crl;
+ if (issuerNames != null)
+ {
+ if (!issuerNames.contains(crl.getIssuerX500Principal()))
+ return false;
+ }
+ BigInteger crlNumber = null;
+ if (maxCrlNumber != null)
+ {
+ try
+ {
+ byte[] b = crl.getExtensionValue(CRL_NUMBER_ID);
+ if (b == null)
+ return false;
+ try
+ {
+ DERValue val = DERReader.read(b);
+ if (!(val.getValue() instanceof BigInteger))
+ return false;
+ crlNumber = (BigInteger) val.getValue();
+ }
+ catch (IOException ioe)
+ {
+ return false;
+ }
+ if (maxCrlNumber.compareTo(crlNumber) < 0)
+ return false;
+ }
+ catch (CertificateParsingException cpe)
+ {
+ return false;
+ }
+ }
+ if (minCrlNumber != null)
+ {
+ try
+ {
+ if (crlNumber == null)
+ {
+ byte[] b = crl.getExtensionValue(CRL_NUMBER_ID);
+ if (b == null)
+ return false;
+ try
+ {
+ DERValue val = DERReader.read(b);
+ if (!(val.getValue() instanceof BigInteger))
+ return false;
+ crlNumber = (BigInteger) val.getValue();
+ }
+ catch (IOException ioe)
+ {
+ return false;
+ }
+ }
+ if (minCrlNumber.compareTo(crlNumber) > 0)
+ return false;
+ }
+ catch (CertificateParsingException cpe)
+ {
+ return false;
+ }
+ }
+ if (date != null)
+ {
+ if (date.compareTo(crl.getThisUpdate()) < 0 ||
+ date.compareTo(crl.getNextUpdate()) > 0)
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns a copy of this object.
+ *
+ * @return The copy.
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException shouldNotHappen)
+ {
+ throw new Error(shouldNotHappen);
+ }
+ }
+}
diff --git a/libjava/java/security/cert/X509CertSelector.java b/libjava/java/security/cert/X509CertSelector.java
new file mode 100644
index 00000000000..c7914c140fd
--- /dev/null
+++ b/libjava/java/security/cert/X509CertSelector.java
@@ -0,0 +1,1111 @@
+/* X509CertSelector.java -- selects X.509 certificates by criteria.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.security.cert;
+
+import java.io.IOException;
+
+import java.math.BigInteger;
+
+import java.security.AccessController;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import gnu.java.security.OID;
+import gnu.java.security.action.GetPropertyAction;
+
+/**
+ * A concrete implementation of {@link CertSelector} for X.509 certificates,
+ * which allows a number of criteria to be set when accepting certificates,
+ * from validity dates, to issuer and subject distinguished names, to some
+ * of the various X.509 extensions.
+ *
+ * null if this value
+ * was not set.
+ *
+ * @return The certificate.
+ */
+ public X509Certificate getCertificate()
+ {
+ return cert;
+ }
+
+ /**
+ * Sets the certificate criterion. If set, only certificates that are
+ * equal to the certificate passed here will be accepted.
+ *
+ * @param cert The certificate.
+ */
+ public void setCertificate(X509Certificate cert)
+ {
+ this.cert = cert;
+ }
+
+ /**
+ * Returns the serial number criterion, or null if this
+ * value was not set.
+ *
+ * @return The serial number.
+ */
+ public BigInteger getSerialNumber()
+ {
+ return serialNo;
+ }
+
+ /**
+ * Sets the serial number of the desired certificate. Only certificates that
+ * contain this serial number are accepted.
+ *
+ * @param serialNo The serial number.
+ */
+ public void setSerialNumber(BigInteger serialNo)
+ {
+ this.serialNo = serialNo;
+ }
+
+ /**
+ * Returns the issuer criterion as a string, or null if this
+ * value was not set.
+ *
+ * @return The issuer.
+ */
+ public String getIssuerAsString()
+ {
+ if (issuer != null)
+ return issuer.getName();
+ else
+ return null;
+ }
+
+ /**
+ * Returns the issuer criterion as a sequence of DER bytes, or
+ * null if this value was not set.
+ *
+ * @return The issuer.
+ */
+ public byte[] getIssuerAsBytes() throws IOException
+ {
+ if (issuer != null)
+ return issuer.getEncoded();
+ else
+ return null;
+ }
+
+ /**
+ * Sets the issuer, specified as a string representation of the issuer's
+ * distinguished name. Only certificates issued by this issuer will
+ * be accepted.
+ *
+ * @param name The string representation of the issuer's distinguished name.
+ * @throws IOException If the given name is incorrectly formatted.
+ */
+ public void setIssuer(String name) throws IOException
+ {
+ if (name != null)
+ {
+ try
+ {
+ issuer = new X500Principal(name);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new IOException(iae.getMessage());
+ }
+ }
+ else
+ issuer = null;
+ }
+
+ /**
+ * Sets the issuer, specified as the DER encoding of the issuer's
+ * distinguished name. Only certificates issued by this issuer will
+ * be accepted.
+ *
+ * @param name The DER encoding of the issuer's distinguished name.
+ * @throws IOException If the given name is incorrectly formatted.
+ */
+ public void setIssuer(byte[] name) throws IOException
+ {
+ if (name != null)
+ {
+ try
+ {
+ issuer = new X500Principal(name);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new IOException(iae.getMessage());
+ }
+ }
+ else
+ issuer = null;
+ }
+
+ /**
+ * Returns the subject criterion as a string, of null if
+ * this value was not set.
+ *
+ * @return The subject.
+ */
+ public String getSubjectAsString()
+ {
+ if (subject != null)
+ return subject.getName();
+ else
+ return null;
+ }
+
+ /**
+ * Returns the subject criterion as a sequence of DER bytes, or
+ * null if this value is not set.
+ *
+ * @return The subject.
+ */
+ public byte[] getSubjectAsBytes() throws IOException
+ {
+ if (subject != null)
+ return subject.getEncoded();
+ else
+ return null;
+ }
+
+ /**
+ * Sets the subject, specified as a string representation of the
+ * subject's distinguished name. Only certificates with the given
+ * subject will be accepted.
+ *
+ * @param name The string representation of the subject's distinguished name.
+ * @throws IOException If the given name is incorrectly formatted.
+ */
+ public void setSubject(String name) throws IOException
+ {
+ if (name != null)
+ {
+ try
+ {
+ subject = new X500Principal(name);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new IOException(iae.getMessage());
+ }
+ }
+ else
+ subject = null;
+ }
+
+ /**
+ * Sets the subject, specified as the DER encoding of the subject's
+ * distinguished name. Only certificates with the given subject will
+ * be accepted.
+ *
+ * @param name The DER encoding of the subject's distinguished name.
+ * @throws IOException If the given name is incorrectly formatted.
+ */
+ public void setSubject(byte[] name) throws IOException
+ {
+ if (name != null)
+ {
+ try
+ {
+ subject = new X500Principal(name);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new IOException(iae.getMessage());
+ }
+ }
+ else
+ subject = null;
+ }
+
+ /**
+ * Returns the subject key identifier criterion, or null if
+ * this value was not set. Note that the byte array is cloned to prevent
+ * modification.
+ *
+ * @return The subject key identifier.
+ */
+ public byte[] getSubjectKeyIdentifier()
+ {
+ if (subjectKeyId != null)
+ return (byte[]) subjectKeyId.clone();
+ else
+ return null;
+ }
+
+ /**
+ * Sets the subject key identifier criterion, or null to clear
+ * this criterion. Note that the byte array is cloned to prevent modification.
+ *
+ * @param subjectKeyId The subject key identifier.
+ */
+ public void setSubjectKeyIdentifier(byte[] subjectKeyId)
+ {
+ this.subjectKeyId = subjectKeyId != null ? (byte[]) subjectKeyId.clone() :
+ null;
+ }
+
+ /**
+ * Returns the authority key identifier criterion, or null if
+ * this value was not set. Note that the byte array is cloned to prevent
+ * modification.
+ *
+ * @return The authority key identifier.
+ */
+ public byte[] getAuthorityKeyIdentifier()
+ {
+ if (authKeyId != null)
+ return (byte[]) authKeyId.clone();
+ else
+ return null;
+ }
+
+ /**
+ * Sets the authority key identifier criterion, or null to clear
+ * this criterion. Note that the byte array is cloned to prevent modification.
+ *
+ * @param subjectKeyId The subject key identifier.
+ */
+ public void setAuthorityKeyIdentifier(byte[] authKeyId)
+ {
+ this.authKeyId = authKeyId != null ? (byte[]) authKeyId.clone() : null;
+ }
+
+ /**
+ * Returns the date at which certificates must be valid, or null
+ * if this criterion was not set.
+ *
+ * @return The target certificate valitity date.
+ */
+ public Date getCertificateValid()
+ {
+ if (certValid != null)
+ return (Date) certValid.clone();
+ else
+ return null;
+ }
+
+ /**
+ * Sets the date at which certificates must be valid. Specify
+ * null to clear this criterion.
+ *
+ * @param certValid The certificate validity date.
+ */
+ public void setCertificateValid(Date certValid)
+ {
+ this.certValid = certValid != null ? (Date) certValid.clone() : null;
+ }
+
+ /**
+ * This method, and its related X.509 certificate extension — the
+ * private key usage period — is not supported under the Internet
+ * PKI for X.509 certificates (PKIX), described in RFC 3280. As such, this
+ * method is not supported either.
+ *
+ * null.
+ *
+ * @return Null.
+ */
+ public Date getPrivateKeyValid()
+ {
+ return null;
+ }
+
+ /**
+ * This method, and its related X.509 certificate extension — the
+ * private key usage period — is not supported under the Internet
+ * PKI for X.509 certificates (PKIX), described in RFC 3280. As such, this
+ * method is not supported either.
+ *
+ * null if this criterion was not set.
+ *
+ * @return The public key algorithm ID.
+ */
+ public String getSubjectPublicKeyAlgID()
+ {
+ return String.valueOf(sigId);
+ }
+
+ /**
+ * Sets the public key algorithm ID that matching certificates must have.
+ * Specify null to clear this criterion.
+ *
+ * @param sigId The public key ID.
+ * @throws IOException If the specified ID is not a valid object identifier.
+ */
+ public void setSubjectPublicKeyAlgID(String sigId) throws IOException
+ {
+ if (sigId != null)
+ {
+ try
+ {
+ OID oid = new OID(sigId);
+ int[] comp = oid.getIDs();
+ if (!checkOid(comp))
+ throw new IOException("malformed OID: " + sigId);
+ this.sigId = oid;
+ }
+ catch (IllegalArgumentException iae)
+ {
+ IOException ioe = new IOException("malformed OID: " + sigId);
+ ioe.initCause(iae);
+ throw ioe;
+ }
+ }
+ else
+ this.sigId = null;
+ }
+
+ /**
+ * Returns the subject public key criterion, or null if this
+ * value is not set.
+ *
+ * @return The subject public key.
+ */
+ public PublicKey getSubjectPublicKey()
+ {
+ return subjectKey;
+ }
+
+ /**
+ * Sets the subject public key criterion as an opaque representation.
+ * Specify null to clear this criterion.
+ *
+ * @param key The public key.
+ */
+ public void setSubjectPublicKey(PublicKey key)
+ {
+ this.subjectKey = key;
+ if (key == null)
+ {
+ subjectKeySpec = null;
+ return;
+ }
+ try
+ {
+ KeyFactory enc = KeyFactory.getInstance("X.509");
+ subjectKeySpec = (X509EncodedKeySpec)
+ enc.getKeySpec(key, X509EncodedKeySpec.class);
+ }
+ catch (Exception x)
+ {
+ subjectKey = null;
+ subjectKeySpec = null;
+ }
+ }
+
+ /**
+ * Sets the subject public key criterion as a DER-encoded key. Specify
+ * null to clear this value.
+ *
+ * @param key The DER-encoded key bytes.
+ * @throws IOException If the argument is not a valid DER-encoded key.
+ */
+ public void setSubjectPublicKey(byte[] key) throws IOException
+ {
+ if (key == null)
+ {
+ subjectKey = null;
+ subjectKeySpec = null;
+ return;
+ }
+ try
+ {
+ subjectKeySpec = new X509EncodedKeySpec(key);
+ KeyFactory enc = KeyFactory.getInstance("X.509");
+ subjectKey = enc.generatePublic(subjectKeySpec);
+ }
+ catch (Exception x)
+ {
+ subjectKey = null;
+ subjectKeySpec = null;
+ IOException ioe = new IOException(x.getMessage());
+ ioe.initCause(x);
+ throw ioe;
+ }
+ }
+
+ /**
+ * Returns the public key usage criterion, or null if this
+ * value is not set. Note that the array is cloned to prevent modification.
+ *
+ * @return The public key usage.
+ */
+ public boolean[] getKeyUsage()
+ {
+ if (keyUsage != null)
+ return (boolean[]) keyUsage.clone();
+ else
+ return null;
+ }
+
+ /**
+ * Sets the public key usage criterion. Specify null to clear
+ * this value.
+ *
+ * @param keyUsage The public key usage.
+ */
+ public void setKeyUsage(boolean[] keyUsage)
+ {
+ this.keyUsage = keyUsage != null ? (boolean[]) keyUsage.clone() : null;
+ }
+
+ /**
+ * Returns the set of extended key purpose IDs, as an unmodifiable set
+ * of OID strings. Returns null if this criterion is not
+ * set.
+ *
+ * @return The set of key purpose OIDs (strings).
+ */
+ public Set getExtendedKeyUsage()
+ {
+ if (keyPurposeSet != null)
+ return Collections.unmodifiableSet(keyPurposeSet);
+ else
+ return null;
+ }
+
+ /**
+ * Sets the extended key usage criterion, as a set of OID strings. Specify
+ * null to clear this value.
+ *
+ * @param keyPurposeSet The set of key purpose OIDs.
+ * @throws IOException If any element of the set is not a valid OID string.
+ */
+ public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException
+ {
+ if (keyPurposeSet == null)
+ {
+ this.keyPurposeSet = null;
+ return;
+ }
+ Set s = new HashSet();
+ for (Iterator it = keyPurposeSet.iterator(); it.hasNext(); )
+ {
+ Object o = it.next();
+ if (!(o instanceof String))
+ throw new IOException("not a string: " + o);
+ try
+ {
+ OID oid = new OID((String) o);
+ int[] comp = oid.getIDs();
+ if (!checkOid(comp))
+ throw new IOException("malformed OID: " + o);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ IOException ioe = new IOException("malformed OID: " + o);
+ ioe.initCause(iae);
+ throw ioe;
+ }
+ }
+ this.keyPurposeSet = s;
+ }
+
+ /**
+ * Returns whether or not all specified alternative names must match.
+ * If false, a certificate is considered a match if one of the
+ * specified alternative names matches.
+ *
+ * @return true if all names must match.
+ */
+ public boolean getMatchAllSubjectAltNames()
+ {
+ return matchAllNames;
+ }
+
+ /**
+ * Sets whether or not all subject alternative names must be matched.
+ * If false, then a certificate will be considered a match if one
+ * alternative name matches.
+ *
+ * @param matchAllNames Whether or not all alternative names must be
+ * matched.
+ */
+ public void setMatchAllSubjectAltNames(boolean matchAllNames)
+ {
+ this.matchAllNames = matchAllNames;
+ }
+
+ /**
+ * Sets the subject alternative names critertion. Each element of the
+ * argument must be a {@link java.util.List} that contains exactly two
+ * elements: the first an {@link Integer}, representing the type of
+ * name, and the second either a {@link String} or a byte array,
+ * representing the name itself.
+ *
+ * @param altNames The alternative names.
+ * @throws IOException If any element of the argument is invalid.
+ */
+ public void setSubjectAlternativeNames(Collection altNames)
+ throws IOException
+ {
+ if (altNames == null)
+ {
+ this.altNames = null;
+ return;
+ }
+ List l = new ArrayList(altNames.size());
+ for (Iterator it = altNames.iterator(); it.hasNext(); )
+ {
+ Object o = it.next();
+ if (!(o instanceof List) || ((List) o).size() != 2 ||
+ !(((List) o).get(0) instanceof Integer) ||
+ !(((List) o).get(1) instanceof String) ||
+ !(((List) o).get(1) instanceof byte[]))
+ throw new IOException("illegal alternative name: " + o);
+ Integer i = (Integer) ((List) o).get(0);
+ if (i.intValue() < 0 || i.intValue() > 8)
+ throw new IOException("illegal alternative name: " + o +
+ ", bad id: " + i);
+ l.add(new ArrayList((List) o));
+ }
+ this.altNames = l;
+ }
+
+ /**
+ * Add a name to the subject alternative names criterion.
+ *
+ * @param id The type of name this is. Must be in the range [0,8].
+ * @param name The name.
+ * @throws IOException If the id is out of range, or if the name
+ * is null.
+ */
+ public void addSubjectAlternativeName(int id, String name)
+ throws IOException
+ {
+ if (id < 0 || id > 8 || name == null)
+ throw new IOException("illegal alternative name");
+ if (altNames == null)
+ altNames = new LinkedList();
+ ArrayList l = new ArrayList(2);
+ l.add(new Integer(id));
+ l.add(name);
+ altNames.add(l);
+ }
+
+ /**
+ * Add a name, as DER-encoded bytes, to the subject alternative names
+ * criterion.
+ *
+ * @param id The type of name this is.
+ */
+ public void addSubjectAlternativeName(int id, byte[] name)
+ throws IOException
+ {
+ if (id < 0 || id > 8 || name == null)
+ throw new IOException("illegal alternative name");
+ if (altNames == null)
+ altNames = new LinkedList();
+ ArrayList l = new ArrayList(2);
+ l.add(new Integer(id));
+ l.add(name);
+ altNames.add(l);
+ }
+
+ /**
+ * Returns the name constraints criterion, or null if this
+ * value is not set. Note that the byte array is cloned to prevent
+ * modification.
+ *
+ * @return The name constraints.
+ */
+ public byte[] getNameConstraints()
+ {
+ if (nameConstraints != null)
+ return (byte[]) nameConstraints.clone();
+ else
+ return null;
+ }
+
+ /**
+ * Sets the name constraints criterion; specify null to
+ * clear this criterion. Note that if non-null, the argument will be
+ * cloned to prevent modification.
+ *
+ * @param nameConstraints The new name constraints.
+ * @throws IOException If the argument is not a valid DER-encoded
+ * name constraints.
+ */
+ public void setNameConstraints(byte[] nameConstraints)
+ throws IOException
+ {
+ // FIXME check if the argument is valid.
+ this.nameConstraints = nameConstraints != null
+ ? (byte[]) nameConstraints.clone() : null;
+ }
+
+ /**
+ * Returns the basic constraints criterion, or -1 if this value is not set.
+ *
+ * @return The basic constraints.
+ */
+ public int getBasicConstraints()
+ {
+ return basicConstraints;
+ }
+
+ /**
+ * Sets the basic constraints criterion. Specify -1 to clear this parameter.
+ *
+ * @param basicConstraints The new basic constraints value.
+ */
+ public void setBasicConstraints(int basicConstraints)
+ {
+ if (basicConstraints < -1)
+ basicConstraints = -1;
+ this.basicConstraints = basicConstraints;
+ }
+
+ // The last two criteria not yet implemented are certificate policies
+ // and path-to-names. Both of these are somewhat advanced extensions
+ // (you could probably count the applications that actually use them
+ // on one hand), and they both have no support in the X509Certificate
+ // class.
+ //
+ // Not having support in X509Certificate is not always a problem; for
+ // example, we can compare DER-encoded values as byte arrays for some
+ // extensions. We can't, however, compare them if they are specified
+ // in a set (as policies are). We need to parse the actual value in the
+ // certificate, and check it against the specified set.
+
+ // FIXME
+// public void setPolicy(Set policy) throws IOException
+// {
+// if (policy != null)
+// {
+// for (Iterator it = policy.iterator(); it.hasNext(); )
+// try
+// {
+// OID oid = new OID((String) it.next());
+// int[] i = oid.getIDs();
+// if (!checkOid(i))
+// throw new IOException("invalid OID");
+// }
+// catch (Exception x)
+// {
+// throw new IOException("invalid OID");
+// }
+// }
+// this.policy = policy != null ? new HashSet(policy) : null;
+// }
+
+ // FIXME
+// public void setPathToNames(Collection names) throws IOException
+// {
+// if (names == null)
+// {
+// this.names = null;
+// return;
+// }
+// for (Iterator it = names.iterator(); it.hasNext(); )
+// {
+// try
+// {
+// List l = (List) it.next();
+// if (l.get(1) instanceof String)
+// addPathToName(((Integer)l.get(0)).intValue(), (String)l.get(1));
+// else
+// addPathToName(((Integer)l.get(0)).intValue(), (byte[])l.get(1));
+// }
+// catch (Exception x)
+// {
+// this.names = null;
+// throw new IOException("invalid names");
+// }
+// }
+// }
+
+ // FIXME
+// public void addPathToName(int id, String name) throws IOException
+// {
+// }
+
+ // FIXME
+// public void addPathToName(int id, byte[] name) throws IOException
+// {
+// }
+
+ // FIXME
+// public Collection getSubjectAlternativeNames()
+// {
+// return null;
+// }
+
+ // FIXME
+// public Set getPolicy()
+// {
+// return null;
+// }
+
+ // FIXME
+// public Collection getPathToNames()
+// {
+// return null;
+// }
+
+ /**
+ * Match a certificate. This method will check the given certificate
+ * against all the enabled criteria of this selector, and will return
+ * true if the given certificate matches.
+ *
+ * @param certificate The certificate to check.
+ * @return true if the certificate matches all criteria.
+ */
+ public boolean match(Certificate certificate)
+ {
+ if (!(certificate instanceof X509Certificate))
+ return false;
+ X509Certificate cert = (X509Certificate) certificate;
+ if (this.cert != null)
+ {
+ try
+ {
+ byte[] e1 = this.cert.getEncoded();
+ byte[] e2 = cert.getEncoded();
+ if (!Arrays.equals(e1, e2))
+ return false;
+ }
+ catch (CertificateEncodingException cee)
+ {
+ return false;
+ }
+ }
+ if (serialNo != null)
+ {
+ if (!serialNo.equals(cert.getSerialNumber()))
+ return false;
+ }
+ if (certValid != null)
+ {
+ try
+ {
+ cert.checkValidity(certValid);
+ }
+ catch (CertificateException ce)
+ {
+ return false;
+ }
+ }
+ if (issuer != null)
+ {
+ if (!issuer.equals(cert.getIssuerX500Principal()))
+ return false;
+ }
+ if (subject != null)
+ {
+ if (!subject.equals(cert.getSubjectX500Principal()))
+ return false;
+ }
+ if (sigId != null)
+ {
+ if (!sigId.equals(cert.getSigAlgOID()))
+ return false;
+ }
+ if (subjectKeyId != null)
+ {
+ byte[] b = cert.getExtensionValue(SUBJECT_KEY_ID);
+ if (!Arrays.equals(b, subjectKeyId))
+ return false;
+ }
+ if (authKeyId != null)
+ {
+ byte[] b = cert.getExtensionValue(AUTH_KEY_ID);
+ if (!Arrays.equals(b, authKeyId))
+ return false;
+ }
+ if (keyUsage != null)
+ {
+ boolean[] b = cert.getKeyUsage();
+ if (!Arrays.equals(b, keyUsage))
+ return false;
+ }
+ if (basicConstraints >= 0)
+ {
+ if (cert.getBasicConstraints() != basicConstraints)
+ return false;
+ }
+ if (keyPurposeSet != null)
+ {
+ List kp = null;
+ try
+ {
+ kp = cert.getExtendedKeyUsage();
+ }
+ catch (CertificateParsingException cpe)
+ {
+ return false;
+ }
+ if (kp == null)
+ return false;
+ for (Iterator it = keyPurposeSet.iterator(); it.hasNext(); )
+ {
+ if (!kp.contains(it.next()))
+ return false;
+ }
+ }
+ if (altNames != null)
+ {
+ Collection an = null;
+ try
+ {
+ an = cert.getSubjectAlternativeNames();
+ }
+ catch (CertificateParsingException cpe)
+ {
+ return false;
+ }
+ if (an == null)
+ return false;
+ int match = 0;
+ for (Iterator it = altNames.iterator(); it.hasNext(); )
+ {
+ List l = (List) it.next();
+ Integer id = (Integer) l.get(0);
+ String s = null;
+ byte[] b = null;
+ if (l.get(1) instanceof String)
+ s = (String) l.get(1);
+ else if (l.get(1) instanceof byte[])
+ b = (byte[]) l.get(1);
+ else
+ return false;
+ for (Iterator it2 = an.iterator(); it2.hasNext(); )
+ {
+ Object o = it2.next();
+ if (!(o instanceof List))
+ continue;
+ List l2 = (List) o;
+ if (l2.size() != 2)
+ continue;
+ if (!id.equals(l2.get(0)))
+ continue;
+ if (s != null && (l2.get(1) instanceof String) &&
+ s.equals(l2.get(1)))
+ match++;
+ else if (b != null && (l2.get(1) instanceof byte[]) &&
+ Arrays.equals(b, (byte[]) l2.get(1)))
+ match++;
+ }
+ if (match == 0 || (matchAllNames && match != altNames.size()))
+ return false;
+ }
+ }
+ if (nameConstraints != null)
+ {
+ byte[] nc = cert.getExtensionValue(NAME_CONSTRAINTS_ID);
+ if (!Arrays.equals(nameConstraints, nc))
+ return false;
+ }
+
+ // FIXME check policies.
+ // FIXME check path-to-names.
+
+ return true;
+ }
+
+ public String toString()
+ {
+ StringBuffer str = new StringBuffer(X509CertSelector.class.getName());
+ GetPropertyAction getProp = new GetPropertyAction("line.separator");
+ String nl = (String) AccessController.doPrivileged(getProp);
+ String eol = ";" + nl;
+ str.append(" {").append(nl);
+ if (cert != null)
+ str.append(" certificate = ").append(cert).append(eol);
+ if (basicConstraints >= 0)
+ str.append(" basic constraints = ").append(basicConstraints).append(eol);
+ if (serialNo != null)
+ str.append(" serial number = ").append(serialNo).append(eol);
+ if (certValid != null)
+ str.append(" valid date = ").append(certValid).append(eol);
+ if (issuer != null)
+ str.append(" issuer = ").append(issuer).append(eol);
+ if (subject != null)
+ str.append(" subject = ").append(subject).append(eol);
+ if (sigId != null)
+ str.append(" signature OID = ").append(sigId).append(eol);
+ if (subjectKey != null)
+ str.append(" subject public key = ").append(subjectKey).append(eol);
+ if (subjectKeyId != null)
+ {
+ str.append(" subject key ID = ");
+ for (int i = 0; i < subjectKeyId.length; i++)
+ {
+ str.append(Character.forDigit((subjectKeyId[i] & 0xF0) >>> 8, 16));
+ str.append(Character.forDigit((subjectKeyId[i] & 0x0F), 16));
+ if (i < subjectKeyId.length - 1)
+ str.append(':');
+ }
+ str.append(eol);
+ }
+ if (authKeyId != null)
+ {
+ str.append(" authority key ID = ");
+ for (int i = 0; i < authKeyId.length; i++)
+ {
+ str.append(Character.forDigit((authKeyId[i] & 0xF0) >>> 8, 16));
+ str.append(Character.forDigit((authKeyId[i] & 0x0F), 16));
+ if (i < authKeyId.length - 1)
+ str.append(':');
+ }
+ str.append(eol);
+ }
+ if (keyUsage != null)
+ {
+ str.append(" key usage = ");
+ for (int i = 0; i < keyUsage.length; i++)
+ str.append(keyUsage[i] ? '1' : '0');
+ str.append(eol);
+ }
+ if (keyPurposeSet != null)
+ str.append(" key purpose = ").append(keyPurposeSet).append(eol);
+ if (altNames != null)
+ str.append(" alternative names = ").append(altNames).append(eol);
+ if (nameConstraints != null)
+ str.append(" name constraints = getInstance must be used to instantiate a given
+ * transformation, optionally with a specific provider.
+ *
+ *
+ *
+ *
+ * Cipher c =
+ * Cipher.getInstance("AES/CBC/PKCS5Padding");"AES/OFB8/NoPadding". If no such number is
+ * specified a provider-specific default value is used.init methods have not been called, and therefore no
+ * transformations can be done.
+ */
+ private static final int INITIAL_STATE = 0;
+
+ /** The underlying cipher service provider interface. */
+ private CipherSpi cipherSpi;
+
+ /** The provider from which this instance came. */
+ private Provider provider;
+
+ /** The transformation requested. */
+ private String transformation;
+
+ /** Our current state (encrypting, wrapping, etc.) */
+ private int state;
+
+
+ // Class methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * opmode argument is {@link #ENCRYPT_MODE}, {@link
+ * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
+ * respectively.cert is an
+ * instance of an {@link java.security.cert.X509Certificate} and its
+ * key usage extension field is incompatible with
+ * opmode then an {@link
+ * java.security.InvalidKeyException} is thrown.init methods overrides the
+ * state of the instance, and is equivalent to creating a new instance
+ * and calling its init method.opmode argument is {@link #ENCRYPT_MODE}, {@link
+ * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
+ * respectively.init methods overrides the
+ * state of the instance, and is equivalent to creating a new instance
+ * and calling its init method.opmode argument is {@link #ENCRYPT_MODE}, {@link
+ * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
+ * respectively.cert is an
+ * instance of an {@link java.security.cert.X509Certificate} and its
+ * key usage extension field is incompatible with
+ * opmode then an {@link
+ * java.security.InvalidKeyException} is thrown.init methods overrides the
+ * state of the instance, and is equivalent to creating a new instance
+ * and calling its init method.opmode argument is {@link #ENCRYPT_MODE}, {@link
+ * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
+ * respectively.init methods overrides the
+ * state of the instance, and is equivalent to creating a new instance
+ * and calling its init method.opmode argument is {@link #ENCRYPT_MODE}, {@link
+ * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
+ * respectively.init methods overrides the
+ * state of the instance, and is equivalent to creating a new instance
+ * and calling its init method.opmode argument is {@link #ENCRYPT_MODE}, {@link
+ * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
+ * respectively.init methods overrides the
+ * state of the instance, and is equivalent to creating a new instance
+ * and calling its init method.opmode argument is {@link #ENCRYPT_MODE}, {@link
+ * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
+ * respectively.init methods overrides the
+ * state of the instance, and is equivalent to creating a new instance
+ * and calling its init method.opmode argument is {@link #ENCRYPT_MODE}, {@link
+ * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
+ * respectively.init methods overrides the
+ * state of the instance, and is equivalent to creating a new instance
+ * and calling its init method.wrappedKey
+ * is not a wrapped key, if the algorithm cannot unwrap this
+ * key, or if the unwrapped key's type differs from the
+ * specified type.
+ * @throws java.security.NoSuchAlgorithmException If
+ * wrappedKeyAlgorithm is not a valid algorithm
+ * name.
+ */
+ public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+ int wrappedKeyType)
+ throws IllegalStateException, InvalidKeyException, NoSuchAlgorithmException
+ {
+ if (cipherSpi == null)
+ {
+ return null;
+ }
+ if (state != UNWRAP_MODE)
+ {
+ throw new IllegalStateException("instance is not for unwrapping");
+ }
+ return cipherSpi.engineUnwrap(wrappedKey, wrappedKeyAlgorithm,
+ wrappedKeyType);
+ }
+
+ /**
+ * Continue a multi-part transformation on an entire byte array,
+ * returning the transformed bytes.
+ *
+ * @param input The input bytes.
+ * @return The transformed bytes.
+ * @throws java.lang.IllegalStateException If this cipher was not
+ * initialized for encryption or decryption.
+ */
+ public final byte[] update(byte[] input) throws IllegalStateException
+ {
+ return update(input, 0, input.length);
+ }
+
+ /**
+ * Continue a multi-part transformation on part of a byte array,
+ * returning the transformed bytes.
+ *
+ * @param input The input bytes.
+ * @param inputOffset The index in the input to start.
+ * @param inputLength The number of bytes to transform.
+ * @return The transformed bytes.
+ * @throws java.lang.IllegalStateException If this cipher was not
+ * initialized for encryption or decryption.
+ */
+ public final byte[] update(byte[] input, int inputOffset, int inputLength)
+ throws IllegalStateException
+ {
+ if (cipherSpi == null)
+ {
+ byte[] b = new byte[inputLength];
+ System.arraycopy(input, inputOffset, b, 0, inputLength);
+ return b;
+ }
+ if (state != ENCRYPT_MODE && state != DECRYPT_MODE)
+ {
+ throw new IllegalStateException(
+ "cipher is not for encrypting or decrypting");
+ }
+ return cipherSpi.engineUpdate(input, inputOffset, inputLength);
+ }
+
+ /**
+ * Continue a multi-part transformation on part of a byte array,
+ * placing the transformed bytes into the given array.
+ *
+ * @param input The input bytes.
+ * @param inputOffset The index in the input to start.
+ * @param inputLength The number of bytes to transform.
+ * @param output The output byte array.
+ * @return The number of transformed bytes.
+ * @throws java.lang.IllegalStateException If this cipher was not
+ * initialized for encryption or decryption.
+ * @throws javax.security.ShortBufferException If there is not enough
+ * room in the output array to hold the transformed bytes.
+ */
+ public final int update(byte[] input, int inputOffset, int inputLength,
+ byte[] output)
+ throws IllegalStateException, ShortBufferException
+ {
+ return update(input, inputOffset, inputLength, output, 0);
+ }
+
+ /**
+ * Continue a multi-part transformation on part of a byte array,
+ * placing the transformed bytes into the given array.
+ *
+ * @param input The input bytes.
+ * @param inputOffset The index in the input to start.
+ * @param inputLength The number of bytes to transform.
+ * @param output The output byte array.
+ * @param outputOffset The index in the output array to start.
+ * @return The number of transformed bytes.
+ * @throws java.lang.IllegalStateException If this cipher was not
+ * initialized for encryption or decryption.
+ * @throws javax.security.ShortBufferException If there is not enough
+ * room in the output array to hold the transformed bytes.
+ */
+ public final int update(byte[] input, int inputOffset, int inputLength,
+ byte[] output, int outputOffset)
+ throws IllegalStateException, ShortBufferException
+ {
+ if (cipherSpi == null)
+ {
+ if (inputLength > output.length - outputOffset)
+ {
+ throw new ShortBufferException();
+ }
+ System.arraycopy(input, inputOffset, output, outputOffset, inputLength);
+ return inputLength;
+ }
+ if (state != ENCRYPT_MODE && state != DECRYPT_MODE)
+ {
+ throw new IllegalStateException(
+ "cipher is not for encrypting or decrypting");
+ }
+ return cipherSpi.engineUpdate(input, inputOffset, inputLength,
+ output, outputOffset);
+ }
+
+ /**
+ * Wrap a key.
+ *
+ * @param key The key to wrap.
+ * @return The wrapped key.
+ * @throws java.lang.IllegalStateException If this instance was not
+ * initialized for key wrapping.
+ * @throws javax.crypto.IllegalBlockSizeException If this instance has
+ * no padding and the key is not a multiple of the block size.
+ * @throws java.security.InvalidKeyException If this instance cannot
+ * wrap this key.
+ */
+ public final byte[] wrap(Key key)
+ throws IllegalStateException, IllegalBlockSizeException, InvalidKeyException
+ {
+ if (cipherSpi == null)
+ {
+ return null;
+ }
+ if (state != WRAP_MODE)
+ {
+ throw new IllegalStateException("instance is not for key wrapping");
+ }
+ return cipherSpi.engineWrap(key);
+ }
+}
diff --git a/libjava/javax/crypto/CipherInputStream.java b/libjava/javax/crypto/CipherInputStream.java
new file mode 100644
index 00000000000..c01cb47ac4c
--- /dev/null
+++ b/libjava/javax/crypto/CipherInputStream.java
@@ -0,0 +1,383 @@
+/* CipherInputStream.java -- Filters input through a cipher.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * This is an {@link java.io.InputStream} that filters its data
+ * through a {@link Cipher} before returning it. The Cipher
+ * argument must have been initialized before it is passed to the
+ * constructor.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class CipherInputStream extends FilterInputStream
+{
+
+ // Constants and variables.
+ // ------------------------------------------------------------------------
+
+ /**
+ * The underlying {@link Cipher} instance.
+ */
+ private Cipher cipher;
+
+ /**
+ * Data that has been transformed but not read.
+ */
+ private byte[] outBuffer;
+
+ /**
+ * The offset into {@link #outBuffer} where valid data starts.
+ */
+ private int outOffset;
+
+ /**
+ * The number of valid bytes in the {@link #outBuffer}.
+ */
+ private int outLength;
+
+ /**
+ * Byte buffer that is filled with raw data from the underlying input
+ * stream.
+ */
+ private byte[][] inBuffer;
+
+ /**
+ * The amount of bytes in inBuffer[0] that may be input to the cipher.
+ */
+ private int inLength;
+
+ /**
+ * We set this when the cipher block size is 1, meaning that we can
+ * transform any amount of data.
+ */
+ private boolean isStream;
+
+ private static final int VIRGIN = 0; // I am born.
+ private static final int LIVING = 1; // I am nailed to the hull.
+ private static final int DYING = 2; // I am eaten by sharks.
+ private static final int DEAD = 3;
+ private int state;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Creates a new input stream with a source input stream and cipher.
+ *
+ * @param in The underlying input stream.
+ * @param cipher The cipher to filter data through.
+ */
+ public CipherInputStream(InputStream in, Cipher cipher)
+ {
+ this(in);
+ this.cipher = cipher;
+ if (!(isStream = cipher.getBlockSize() == 1))
+ {
+ inBuffer = new byte[2][];
+ inBuffer[0] = new byte[cipher.getBlockSize()];
+ inBuffer[1] = new byte[cipher.getBlockSize()];
+ inLength = 0;
+ outBuffer = new byte[cipher.getBlockSize()];
+ outOffset = outLength = 0;
+ state = VIRGIN;
+ }
+ }
+
+ /**
+ * Creates a new input stream without a cipher. This constructor is
+ * protected because this class does not work without an
+ * underlying cipher.
+ *
+ * @param in The underlying input stream.
+ */
+ protected CipherInputStream(InputStream in)
+ {
+ super(in);
+ }
+
+ // Instance methods overriding java.io.FilterInputStream.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the number of bytes available without blocking. The value
+ * returned by this method is never greater than the underlying
+ * cipher's block size.
+ *
+ * @return The number of bytes immediately available.
+ * @throws java.io.IOException If an I/O exception occurs.
+ */
+ public int available() throws IOException
+ {
+ if (isStream)
+ return super.available();
+ return outLength - outOffset;
+ }
+
+ /**
+ * Close this input stream. This method merely calls the {@link
+ * java.io.InputStream#close()} method of the underlying input stream.
+ *
+ * @throws java.io.IOException If an I/O exception occurs.
+ */
+ public void close() throws IOException
+ {
+ super.close();
+ }
+
+ /**
+ * Read a single byte from this input stream; returns -1 on the
+ * end-of-file.
+ *
+ * @return The byte read, or -1 if there are no more bytes.
+ * @throws java.io.IOExcpetion If an I/O exception occurs.
+ */
+ public int read() throws IOException
+ {
+ if (isStream)
+ {
+ byte[] buf = new byte[1];
+ int in = super.read();
+ if (in == -1)
+ return -1;
+ buf[0] = (byte) in;
+ try
+ {
+ cipher.update(buf, 0, 1, buf, 0);
+ }
+ catch (ShortBufferException shouldNotHappen)
+ {
+ throw new IOException(shouldNotHappen.getMessage());
+ }
+ return buf[0] & 0xFF;
+ }
+ if (state == DEAD) return -1;
+ if (available() == 0) nextBlock();
+ if (state == DEAD) return -1;
+ return outBuffer[outOffset++] & 0xFF;
+ }
+
+ /**
+ * Read bytes into an array, returning the number of bytes read or -1
+ * on the end-of-file.
+ *
+ * @param buf The byte array to read into.
+ * @param off The offset in buf to start.
+ * @param len The maximum number of bytes to read.
+ * @return The number of bytes read, or -1 on the end-of-file.
+ * @throws java.io.IOException If an I/O exception occurs.
+ */
+ public int read(byte[] buf, int off, int len) throws IOException
+ {
+ if (isStream)
+ {
+ len = super.read(buf, off, len);
+ try
+ {
+ cipher.update(buf, off, len, buf, off);
+ }
+ catch (ShortBufferException shouldNotHappen)
+ {
+ throw new IOException(shouldNotHappen.getMessage());
+ }
+ return len;
+ }
+
+ int count = 0;
+ while (count < len)
+ {
+ if (available() == 0)
+ nextBlock();
+ if (state == DEAD)
+ {
+ if (count > 0) return count;
+ else return -1;
+ }
+ int l = Math.min(available(), len - count);
+ System.arraycopy(outBuffer, outOffset, buf, count+off, l);
+ count += l;
+ outOffset = outLength = 0;
+ }
+ return count;
+ }
+
+ /**
+ * Read bytes into an array, returning the number of bytes read or -1
+ * on the end-of-file.
+ *
+ * @param buf The byte arry to read into.
+ * @return The number of bytes read, or -1 on the end-of-file.
+ * @throws java.io.IOException If an I/O exception occurs.
+ */
+ public int read(byte[] buf) throws IOException
+ {
+ return read(buf, 0, buf.length);
+ }
+
+ /**
+ * Skip a number of bytes. This class only supports skipping as many
+ * bytes as are returned by {@link #available()}, which is the number
+ * of transformed bytes currently in this class's internal buffer.
+ *
+ * @param bytes The number of bytes to skip.
+ * @return The number of bytes skipped.
+ */
+ public long skip(long bytes) throws IOException
+ {
+ if (isStream)
+ {
+ return super.skip(bytes);
+ }
+ long ret = 0;
+ if (bytes > 0 && available() > 0)
+ {
+ ret = available();
+ outOffset = outLength = 0;
+ }
+ return ret;
+ }
+
+ /**
+ * Returns whether or not this input stream supports the {@link
+ * #mark(long)} and {@link #reset()} methods; this input stream does
+ * not, however, and invariably returns false.
+ *
+ * @return false
+ */
+ public boolean markSupported()
+ {
+ return false;
+ }
+
+ /**
+ * Set the mark. This method is unsupported and is empty.
+ *
+ * @param mark Is ignored.
+ */
+ public void mark(long mark)
+ {
+ }
+
+ /**
+ * Reset to the mark. This method is unsupported and is empty.
+ */
+ public void reset() throws IOException
+ {
+ throw new IOException("reset not supported");
+ }
+
+ // Own methods.
+ // -------------------------------------------------------------------------
+
+ private void nextBlock() throws IOException
+ {
+ byte[] temp = inBuffer[0];
+ inBuffer[0] = inBuffer[1];
+ inBuffer[1] = temp;
+ int count = 0;
+ boolean eof = false;
+
+ if (state == VIRGIN || state == LIVING)
+ {
+ do
+ {
+ int l = in.read(inBuffer[1], count, inBuffer[1].length - count);
+ if (l == -1)
+ {
+ eof = true;
+ break;
+ }
+ count += l;
+ }
+ while (count < inBuffer[1].length);
+ }
+
+ try
+ {
+ switch (state)
+ {
+ case VIRGIN:
+ state = LIVING;
+ nextBlock();
+ break;
+ case LIVING:
+ if (eof)
+ {
+ if (count > 0)
+ {
+ outOffset = cipher.update(inBuffer[0], 0, inLength, outBuffer, 0);
+ state = DYING;
+ }
+ else
+ {
+ outOffset = cipher.doFinal(inBuffer[0], 0, inLength, outBuffer, 0);
+ state = DEAD;
+ }
+ }
+ else
+ {
+ outOffset = cipher.update(inBuffer[0], 0, inLength, outBuffer, 0);
+ }
+ break;
+ case DYING:
+ outOffset = cipher.doFinal(inBuffer[0], 0, inLength, outBuffer, 0);
+ state = DEAD;
+ break;
+ case DEAD:
+ }
+ }
+ catch (ShortBufferException sbe)
+ {
+ throw new IOException(sbe.toString());
+ }
+ catch (BadPaddingException bpe)
+ {
+ throw new IOException(bpe.toString());
+ }
+ catch (IllegalBlockSizeException ibse)
+ {
+ throw new IOException(ibse.toString());
+ }
+ inLength = count;
+ }
+}
diff --git a/libjava/javax/crypto/CipherOutputStream.java b/libjava/javax/crypto/CipherOutputStream.java
new file mode 100644
index 00000000000..7eb09c1d08c
--- /dev/null
+++ b/libjava/javax/crypto/CipherOutputStream.java
@@ -0,0 +1,268 @@
+/* CipherOutputStream.java -- Filters output through a cipher.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A filtered output stream that transforms data written to it with a
+ * {@link Cipher} before sending it to the underlying output stream.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class CipherOutputStream extends FilterOutputStream
+{
+
+ // Fields.
+ // ------------------------------------------------------------------------
+
+ /** The underlying cipher. */
+ private Cipher cipher;
+
+ private byte[][] inBuffer;
+
+ private int inLength;
+
+ private byte[] outBuffer;
+
+ private static final int FIRST_TIME = 0;
+ private static final int SECOND_TIME = 1;
+ private static final int SEASONED = 2;
+ private int state;
+
+ /** True if the cipher is a stream cipher (blockSize == 1) */
+ private boolean isStream;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new cipher output stream. The cipher argument must have
+ * already been initialized.
+ *
+ * @param out The sink for transformed data.
+ * @param cipher The cipher to transform data with.
+ */
+ public CipherOutputStream(OutputStream out, Cipher cipher)
+ {
+ super(out);
+ if (cipher != null)
+ {
+ this.cipher = cipher;
+ if (!(isStream = cipher.getBlockSize() == 1))
+ {
+ inBuffer = new byte[2][];
+ inBuffer[0] = new byte[cipher.getBlockSize()];
+ inBuffer[1] = new byte[cipher.getBlockSize()];
+ inLength = 0;
+ state = FIRST_TIME;
+ }
+ }
+ else
+ this.cipher = new NullCipher();
+ }
+
+ /**
+ * Create a cipher output stream with no cipher.
+ *
+ * @param out The sink for transformed data.
+ */
+ protected CipherOutputStream(OutputStream out)
+ {
+ super(out);
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Close this output stream, and the sink output stream.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cipher.algorithmCipher.algorithm/modeCipher.algorithm//paddingCipher.algorithm/mode/padding
+ *
+ *
+ * CipherSpi implementation
+ * for "algorithm", return it. Otherwise throw a {@link
+ * java.security.NoSuchAlgorithmException}.
+ *
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public abstract class CipherSpi
+{
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new CipherSpi.
+ */
+ public CipherSpi()
+ {
+ }
+
+ // Abstract methods to be implemented by providers.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Finishes a multi-part transformation or transforms a portion of a
+ * byte array, and returns the transformed bytes.
+ *
+ * @param input The input bytes.
+ * @param inputOffset The index in the input at which to start.
+ * @param inputLength The number of bytes to transform.
+ * @return The transformed bytes in a new array.
+ * @throws javax.crypto.IllegalBlockSizeException If this instance has
+ * no padding and the input size is not a multiple of the
+ * block size.
+ * @throws javax.crypto.BadPaddingException If this instance is being
+ * used for decryption and the padding is not appropriate for
+ * this instance's padding scheme.
+ */
+ protected abstract byte[]
+ engineDoFinal(byte[] input, int inputOffset, int inputLength)
+ throws IllegalBlockSizeException, BadPaddingException;
+
+ /**
+ * Finishes a multi-part transformation or transforms a portion of a
+ * byte array, and stores the transformed bytes in the supplied array.
+ *
+ * @param input The input bytes.
+ * @param inputOffset The index in the input at which to start.
+ * @param inputLength The number of bytes to transform.
+ * @param output The output byte array.
+ * @param outputOffset The index in the output array at which to start.
+ * @return The number of transformed bytes stored in the output array.
+ * @throws javax.crypto.IllegalBlockSizeException If this instance has
+ * no padding and the input size is not a multiple of the
+ * block size.
+ * @throws javax.crypto.BadPaddingException If this instance is being
+ * used for decryption and the padding is not appropriate for
+ * this instance's padding scheme.
+ * @throws javax.crypto.ShortBufferException If there is not enough
+ * space in the output array for the transformed bytes.
+ */
+ protected abstract int
+ engineDoFinal(byte[] input, int inputOffset, int inputLength,
+ byte[] output, int outputOffset)
+ throws IllegalBlockSizeException, BadPaddingException, ShortBufferException;
+
+ /**
+ * Returns the block size of the underlying cipher.
+ *
+ * @return The block size.
+ */
+ protected abstract int engineGetBlockSize();
+
+ /**
+ * Returns the initializaiton vector this cipher was initialized with,
+ * if any.
+ *
+ * @return The IV, or null if this cipher uses no IV or if this
+ * instance has not been initialized yet.
+ */
+ protected abstract byte[] engineGetIV();
+
+ /**
+ * CipherSpi subclass for
+ * "algorithm/mode/padding", return it. Otherwise
+ * go to step 2.CipherSpi subclass for
+ * "algorithm/mode", instatiate it, call {@link
+ * #engineSetPadding(java.lang.String)} for the padding name, and return
+ * it. Otherwise go to step 3.CipherSpi subclass for
+ * "algorithm//padding", instatiate it, call {@link
+ * #engineSetMode(java.lang.String)} for the mode name, and return
+ * it. Otherwise go to step 4.CipherSpi subclass for
+ * "algorithm", instatiate it, call {@link
+ * #engineSetMode(java.lang.String)} for the mode name, call {@link
+ * #engineSetPadding(java.lang.String)} for the padding name, and return
+ * it. Otherwise throw a {@link java.security.NoSuchAlgorithmException}.abstract, and the default implementation will throw an
+ * {@link java.lang.UnsupportedOperationException}. Concrete
+ * subclasses should override this method to return the correct
+ * value.null if this
+ * cipher does not use parameters.
+ */
+ protected abstract AlgorithmParameters engineGetParameters();
+
+ /**
+ * Initializes this cipher with an operation mode, key, and source of
+ * randomness. If this cipher requires any other initializing data,
+ * for example an initialization vector, then it should generate it
+ * from the provided source of randomness.
+ *
+ * @param opmode The operation mode, one of {@link
+ * Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
+ * Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
+ * @param key The key to initialize this cipher with.
+ * @param random The source of random bytes to use.
+ * @throws java.security.InvalidKeyException If the given key is not
+ * acceptable for this implementation.
+ */
+ protected abstract void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException;
+
+ /**
+ * Initializes this cipher with an operation mode, key, parameters,
+ * and source of randomness. If this cipher requires any other
+ * initializing data, for example an initialization vector, then it should
+ * generate it from the provided source of randomness.
+ *
+ * @param opmode The operation mode, one of {@link
+ * Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
+ * Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
+ * @param key The key to initialize this cipher with.
+ * @param params The algorithm parameters to initialize with.
+ * @param random The source of random bytes to use.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * given parameters are not appropriate for this
+ * implementation.
+ * @throws java.security.InvalidKeyException If the given key is not
+ * acceptable for this implementation.
+ */
+ protected abstract void
+ engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException, InvalidKeyException;
+
+ /**
+ * Initializes this cipher with an operation mode, key, parameters,
+ * and source of randomness. If this cipher requires any other
+ * initializing data, for example an initialization vector, then it should
+ * generate it from the provided source of randomness.
+ *
+ * @param opmode The operation mode, one of {@link
+ * Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
+ * Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
+ * @param key The key to initialize this cipher with.
+ * @param params The algorithm parameters to initialize with.
+ * @param random The source of random bytes to use.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * given parameters are not appropriate for this
+ * implementation.
+ * @throws java.security.InvalidKeyException If the given key is not
+ * acceptable for this implementation.
+ */
+ protected abstract void
+ engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException, InvalidKeyException;
+
+ /**
+ * Set the mode in which this cipher is to run.
+ *
+ * @param mode The name of the mode to use.
+ * @throws java.security.NoSuchAlgorithmException If the mode is
+ * not supported by this cipher's provider.
+ */
+ protected abstract void engineSetMode(String mode)
+ throws NoSuchAlgorithmException;
+
+ /**
+ * Set the method with which the input is to be padded.
+ *
+ * @param padding The name of the padding to use.
+ * @throws javax.crypto.NoSuchPaddingException If the padding is not
+ * supported by this cipher's provider.
+ */
+ protected abstract void engineSetPadding(String padding)
+ throws NoSuchPaddingException;
+
+ /**
+ * abstract, and the default implementation will throw an
+ * {@link java.lang.UnsupportedOperationException}.wrappedKeyType is an
+ * inappropriate type for the unwrapped key.
+ * @throws java.security.NoSuchAlgorithmException If the
+ * wrappedKeyAlgorithm is unknown.
+ */
+ protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+ int wrappedKeyType)
+ throws InvalidKeyException, NoSuchAlgorithmException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Continue with a multi-part transformation, returning a new array of
+ * the transformed bytes.
+ *
+ * @param input The next input bytes.
+ * @param inputOffset The index in the input array from which to start.
+ * @param inputLength The number of bytes to input.
+ * @return The transformed bytes.
+ */
+ protected abstract byte[]
+ engineUpdate(byte[] input, int inputOffset, int inputLength);
+
+ /**
+ * Continue with a multi-part transformation, storing the transformed
+ * bytes into the specified array.
+ *
+ * @param input The next input bytes.
+ * @param inputOffset The index in the input from which to start.
+ * @param inputLength The number of bytes to input.
+ * @param output The output buffer.
+ * @param outputOffset The index in the output array from which to start.
+ * @return The transformed bytes.
+ * @throws javax.crypto.ShortBufferException If there is not enough
+ * space in the output array to store the transformed bytes.
+ */
+ protected abstract int
+ engineUpdate(byte[] input, int inputOffset, int inputLength,
+ byte[] output, int outputOffset)
+ throws ShortBufferException;
+
+ /**
+ * abstract, and the default implementation will throw an
+ * {@link java.lang.UnsupportedOperationException}.EncryptedPrivateKeyInfo ASN.1
+ * type as specified in PKCS #8 -
+ * Private-Key Information Syntax Standard.
+ *
+ * EncryptedPrivateKeyInfo is:
+ *
+ *
+ *
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see java.security.spec.PKCS8EncodedKeySpec
+ */
+public class EncryptedPrivateKeyInfo
+{
+
+ // Fields.
+ // ------------------------------------------------------------------------
+
+ /** The encrypted data. */
+ private byte[] encryptedData;
+
+ /** The encoded, encrypted key. */
+ private byte[] encoded;
+
+ /** The OID of the encryption algorithm. */
+ private OID algOid;
+
+ /** The encryption algorithm's parameters. */
+ private AlgorithmParameters params;
+
+ /** The encoded ASN.1 algorithm parameters. */
+ private byte[] encodedParams;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new EncryptedPrivateKeyInfo ::= SEQUENCE {
+ * encryptionAlgorithm EncryptionAlgorithmIdentifier,
+ * encryptedData EncryptedData }
+ *
+ * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * EncrytpedData ::= OCTET STRING
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ * EncryptedPrivateKeyInfo object from raw
+ * encrypted data and the parameters used for encryption.
+ *
+ * encryptedData array is cloned.
+ *
+ * @param params The encryption algorithm parameters.
+ * @param encryptedData The encrypted key data.
+ * @throws java.lang.IllegalArgumentException If the
+ * encryptedData array is empty (zero-length).
+ * @throws java.security.NoSuchAlgorithmException If the algorithm
+ * specified in the parameters is not supported.
+ * @throws java.lang.NullPointerException If encryptedData
+ * is null.
+ */
+ public EncryptedPrivateKeyInfo(AlgorithmParameters params,
+ byte[] encryptedData)
+ throws IllegalArgumentException, NoSuchAlgorithmException
+ {
+ if (encryptedData.length == 0)
+ {
+ throw new IllegalArgumentException("0-length encryptedData");
+ }
+ this.params = params;
+ algOid = new OID(params.getAlgorithm());
+ this.encryptedData = (byte[]) encryptedData.clone();
+ }
+
+ /**
+ * Create a new EncryptedPrivateKeyInfo from an encoded
+ * representation, parsing the ASN.1 sequence.
+ *
+ * @param encoded The encoded info.
+ * @throws java.io.IOException If parsing the encoded data fails.
+ * @throws java.lang.NullPointerException If encoded is
+ * null.
+ */
+ public EncryptedPrivateKeyInfo(byte[] encoded)
+ throws IOException
+ {
+ this.encoded = (byte[]) encoded.clone();
+ decode();
+ }
+
+ /**
+ * Create a new EncryptedPrivateKeyInfo from the cipher
+ * name and the encrytpedData.
+ *
+ * encryptedData array is cloned.
+ *
+ * @param algName The name of the algorithm (as an object identifier).
+ * @param encryptedData The encrypted key data.
+ * @throws java.lang.IllegalArgumentException If the
+ * encryptedData array is empty (zero-length).
+ * @throws java.security.NoSuchAlgorithmException If algName is not
+ * the name of a supported algorithm.
+ * @throws java.lang.NullPointerException If encryptedData
+ * is null.
+ */
+ public EncryptedPrivateKeyInfo(String algName, byte[] encryptedData)
+ throws IllegalArgumentException, NoSuchAlgorithmException,
+ NullPointerException
+ {
+ if (encryptedData.length == 0)
+ {
+ throw new IllegalArgumentException("0-length encryptedData");
+ }
+ this.algOid = new OID(algName);
+ this.encryptedData = (byte[]) encryptedData.clone();
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Return the name of the cipher used to encrypt this key.
+ *
+ * @return The algorithm name.
+ */
+ public String getAlgName()
+ {
+ return algOid.toString();
+ }
+
+ public AlgorithmParameters getAlgParameters()
+ {
+ if (params == null && encodedParams != null)
+ {
+ try
+ {
+ params = AlgorithmParameters.getInstance(getAlgName());
+ params.init(encodedParams);
+ }
+ catch (NoSuchAlgorithmException ignore)
+ {
+ }
+ catch (IOException ignore)
+ {
+ }
+ }
+ return params;
+ }
+
+ public synchronized byte[] getEncoded() throws IOException
+ {
+ if (encoded == null) encode();
+ return (byte[]) encoded.clone();
+ }
+
+ public byte[] getEncryptedData()
+ {
+ return encryptedData;
+ }
+
+ public PKCS8EncodedKeySpec getKeySpec(Cipher cipher)
+ throws InvalidKeySpecException
+ {
+ try
+ {
+ return new PKCS8EncodedKeySpec(cipher.doFinal(encryptedData));
+ }
+ catch (Exception x)
+ {
+ throw new InvalidKeySpecException(x.toString());
+ }
+ }
+
+ // Own methods.
+ // -------------------------------------------------------------------------
+
+ private void decode() throws IOException
+ {
+ DERReader der = new DERReader(encoded);
+ DERValue val = der.read();
+ if (val.getTag() != DER.SEQUENCE)
+ throw new IOException("malformed EncryptedPrivateKeyInfo");
+ val = der.read();
+ if (val.getTag() != DER.SEQUENCE)
+ throw new IOException("malformed AlgorithmIdentifier");
+ int algpLen = val.getLength();
+ DERValue oid = der.read();
+ if (oid.getTag() != DER.OBJECT_IDENTIFIER)
+ throw new IOException("malformed AlgorithmIdentifier");
+ algOid = (OID) oid.getValue();
+ if (algpLen == 0)
+ {
+ val = der.read();
+ if (val.getTag() != 0)
+ {
+ encodedParams = val.getEncoded();
+ der.read();
+ }
+ }
+ else if (oid.getEncodedLength() < val.getLength())
+ {
+ val = der.read();
+ encodedParams = val.getEncoded();
+ }
+ val = der.read();
+ if (val.getTag() != DER.OCTET_STRING)
+ throw new IOException("malformed AlgorithmIdentifier");
+ encryptedData = (byte[]) val.getValue();
+ }
+
+ private void encode() throws IOException
+ {
+ List algId = new ArrayList(2);
+ algId.add(new DERValue(DER.OBJECT_IDENTIFIER, algOid));
+ getAlgParameters();
+ if (params != null)
+ {
+ algId.add(DERReader.read(params.getEncoded()));
+ }
+ List epki = new ArrayList(2);
+ epki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, algId));
+ epki.add(new DERValue(DER.OCTET_STRING, encryptedData));
+ encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, epki).getEncoded();
+ }
+}
diff --git a/libjava/javax/crypto/ExemptionMechanism.java b/libjava/javax/crypto/ExemptionMechanism.java
new file mode 100644
index 00000000000..7fa658e9e37
--- /dev/null
+++ b/libjava/javax/crypto/ExemptionMechanism.java
@@ -0,0 +1,226 @@
+/* ExemptionMechanism.java -- Generic crypto-weakening mechanism.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.lang.reflect.InvocationTargetException;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+
+import gnu.java.security.Engine;
+
+/**
+ * An exemption mechanism, which will conditionally allow cryptography
+ * where it is not normally allowed, implements things such as key
+ * recovery, key weakening, or key escrow.
+ *
+ * lastPhase flag set to true.
+ *
+ * @param key The key for this phase.
+ * @param lastPhase Should be true if this will be the
+ * last phase before generating the shared secret.
+ * @return The intermediate result, or null if there is
+ * no intermediate result.
+ * @throws java.lang.IllegalStateException If this instance has not
+ * been initialized.
+ * @throws java.security.InvalidKeyException If the key is
+ * inappropriate for this algorithm.
+ */
+ public final Key doPhase(Key key, boolean lastPhase)
+ throws IllegalStateException, InvalidKeyException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ return kaSpi.engineDoPhase(key, lastPhase);
+ }
+
+ /**
+ * Generate the shared secret in a new byte array.
+ *
+ * @return The shared secret.
+ * @throws java.lang.IllegalStateException If this instnace has not
+ * been initialized, or if not enough calls to
+ * doPhase have been made.
+ */
+ public final byte[] generateSecret() throws IllegalStateException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ return kaSpi.engineGenerateSecret();
+ }
+
+ /**
+ * Generate the shared secret and store it into the supplied array.
+ *
+ * @param sharedSecret The array in which to store the secret.
+ * @param offset The index in sharedSecret to start
+ * storing data.
+ * @return The length of the shared secret, in bytes.
+ * @throws java.lang.IllegalStateException If this instnace has not
+ * been initialized, or if not enough calls to
+ * doPhase have been made.
+ * @throws javax.crypto.ShortBufferException If the supplied array is
+ * not large enough to store the result.
+ */
+ public final int generateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ return kaSpi.engineGenerateSecret(sharedSecret, offset);
+ }
+
+ /**
+ * Generate the shared secret and return it as an appropriate {@link
+ * SecretKey}.
+ *
+ * @param algorithm The secret key's algorithm.
+ * @return The shared secret as a secret key.
+ * @throws java.lang.IllegalStateException If this instnace has not
+ * been initialized, or if not enough calls to
+ * doPhase have been made.
+ * @throws java.security.InvalidKeyException If the shared secret
+ * cannot be used to make a {@link SecretKey}.
+ * @throws java.security.NoSuchAlgorithmException If the specified
+ * algorithm does not exist.
+ */
+ public final SecretKey generateSecret(String algorithm)
+ throws IllegalStateException, InvalidKeyException, NoSuchAlgorithmException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ return kaSpi.engineGenerateSecret(algorithm);
+ }
+
+ /**
+ * Return the name of this key-agreement algorithm.
+ *
+ * @return The algorithm name.
+ */
+ public final String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * Return the provider of the underlying implementation.
+ *
+ * @return The provider.
+ */
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Initialize this key agreement with a key. This method will use the
+ * highest-priority {@link java.security.SecureRandom} as its source
+ * of randomness.
+ *
+ * @param key The key, usually the user's private key.
+ * @throws java.security.InvalidKeyException If the supplied key is
+ * not appropriate.
+ */
+ public final void init(Key key) throws InvalidKeyException
+ {
+ init(key, new SecureRandom());
+ }
+
+ /**
+ * Initialize this key agreement with a key and a source of
+ * randomness.
+ *
+ * @param key The key, usually the user's private key.
+ * @param random The source of randomness.
+ * @throws java.security.InvalidKeyException If the supplied key is
+ * not appropriate.
+ */
+ public final void init(Key key, SecureRandom random)
+ throws InvalidKeyException
+ {
+ kaSpi.engineInit(key, random);
+ virgin = false; // w00t!
+ }
+
+ /**
+ * Initialize this key agreement with a key and parameters. This
+ * method will use the highest-priority {@link
+ * java.security.SecureRandom} as its source of randomness.
+ *
+ * @param key The key, usually the user's private key.
+ * @param params The algorithm parameters.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * supplied parameters are not appropriate.
+ * @throws java.security.InvalidKeyException If the supplied key is
+ * not appropriate.
+ */
+ public final void init(Key key, AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException, InvalidKeyException
+ {
+ init(key, params, new SecureRandom());
+ }
+
+ /**
+ * Initialize this key agreement with a key, parameters, and source of
+ * randomness.
+ *
+ * @param key The key, usually the user's private key.
+ * @param params The algorithm parameters.
+ * @param random The source of randomness.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * supplied parameters are not appropriate.
+ * @throws java.security.InvalidKeyException If the supplied key is
+ * not appropriate.
+ */
+ public final void init(Key key, AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException, InvalidKeyException
+ {
+ kaSpi.engineInit(key, params, random);
+ virgin = false; // w00t!
+ }
+}
diff --git a/libjava/javax/crypto/KeyAgreementSpi.java b/libjava/javax/crypto/KeyAgreementSpi.java
new file mode 100644
index 00000000000..231f112794b
--- /dev/null
+++ b/libjava/javax/crypto/KeyAgreementSpi.java
@@ -0,0 +1,160 @@
+/* KeyAgreementSpi.java -- The key agreement service provider interface.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * This is the Service Provider Interface (SPI) for the
+ * {@link javax.crypto.KeyAgreement} class.
+ *
+ * "KeyAgreement").
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see KeyAgreement
+ * @see SecretKey
+ */
+public abstract class KeyAgreementSpi
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new KeyAgreementSpi instance.
+ */
+ public KeyAgreementSpi()
+ {
+ }
+
+ // Abstract instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Do a phase in the key agreement.
+ *
+ * @param key The key to use for this phase.
+ * @param lastPhase true if this call should be the last
+ * phase.
+ * @return The intermediate result, or null if there is
+ * no intermediate result.
+ * @throws java.lang.IllegalStateException If this instance has not
+ * been initialized.
+ * @throws java.security.InvalidKeyException If the supplied key is
+ * not appropriate.
+ */
+ protected abstract Key engineDoPhase(Key key, boolean lastPhase)
+ throws IllegalStateException, InvalidKeyException;
+
+ /**
+ * Generate the shared secret in a new byte array.
+ *
+ * @return The shared secret in a new byte array.
+ * @throws java.lang.IllegalStateException If this key agreement is
+ * not ready to generate the secret.
+ */
+ protected abstract byte[] engineGenerateSecret()
+ throws IllegalStateException;
+
+ /**
+ * Generate the shared secret, storing it into the specified array.
+ *
+ * @param sharedSecret The byte array in which to store the secret.
+ * @param offset The offset into the byte array to start.
+ * @return The size of the shared secret.
+ * @throws java.lang.IllegalStateException If this key agreement is
+ * not ready to generate the secret.
+ * @throws javax.crypto.ShortBufferException If there is not enough
+ * space in the supplied array for the shared secret.
+ */
+ protected abstract int engineGenerateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException;
+
+ /**
+ * Generate the shared secret and return it as a {@link SecretKey}.
+ *
+ * @param algorithm The algorithm with which to generate the secret key.
+ * @return The shared secret as a secret key.
+ * @throws java.lang.IllegalStateException If this key agreement is
+ * not ready to generate the secret.
+ * @throws java.security.InvalidKeyException If the shared secret
+ * cannot be made into a {@link SecretKey}.
+ * @throws java.security.NoSuchAlgorithmException If
+ * algorithm cannot be found.
+ */
+ protected abstract SecretKey engineGenerateSecret(String algorithm)
+ throws IllegalStateException, InvalidKeyException, NoSuchAlgorithmException;
+
+ /**
+ * Initialize this key agreement with a key, parameters, and source of
+ * randomness.
+ *
+ * @param key The key to initialize with, usually a private key.
+ * @param params The parameters to initialize with.
+ * @param random The source of randomness to use.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * supplied parameters are inappropriate.
+ * @throws java.security.InvalidKeyException If the supplied key is
+ * inappropriate.
+ */
+ protected abstract void engineInit(Key key, AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException, InvalidKeyException;
+
+ /**
+ * Initialize this key agreement with a key and source of randomness.
+ *
+ * @param key The key to initialize with, usually a private key.
+ * @param random The source of randomness to use.
+ * @throws java.security.InvalidKeyException If the supplied key is
+ * inappropriate.
+ */
+ protected abstract void engineInit(Key key, SecureRandom random)
+ throws InvalidKeyException;
+}
diff --git a/libjava/javax/crypto/KeyGenerator.java b/libjava/javax/crypto/KeyGenerator.java
new file mode 100644
index 00000000000..35753b036de
--- /dev/null
+++ b/libjava/javax/crypto/KeyGenerator.java
@@ -0,0 +1,284 @@
+/* KeyGenerator.java -- Interface to a symmetric key generator.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.lang.reflect.InvocationTargetException;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+
+import gnu.java.security.Engine;
+
+/**
+ * A generic producer of keys for symmetric cryptography. The keys
+ * returned may be simple wrappers around byte arrays, or, if the
+ * target cipher requires them, more complex objects.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see Cipher
+ * @see Mac
+ */
+public class KeyGenerator
+{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------------
+
+ private static final String SERVICE = "KeyGenerator";
+
+ /** The underlying generator implementation. */
+ private KeyGeneratorSpi kgSpi;
+
+ /** The provider of the implementation. */
+ private Provider provider;
+
+ /** The name of the algorithm. */
+ private String algorithm;
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new key generator.
+ *
+ * @param kgSpi The underlying generator.
+ * @param provider The provider of this implementation.
+ * @param algorithm The algorithm's name.
+ */
+ protected KeyGenerator(KeyGeneratorSpi kgSpi, Provider provider,
+ String algorithm)
+ {
+ this.kgSpi = kgSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new key generator, returning the first available
+ * implementation.
+ *
+ * @param algorithm The generator algorithm name.
+ * @throws java.security.NoSuchAlgorithmException If the specified
+ * algorithm does not exist.
+ */
+ public static final KeyGenerator getInstance(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] provs = Security.getProviders();
+ String msg = algorithm;
+ for (int i = 0; i < provs.length; i++)
+ {
+ try
+ {
+ return getInstance(algorithm, provs[i]);
+ }
+ catch (NoSuchAlgorithmException nsae)
+ {
+ msg = nsae.getMessage();
+ }
+ }
+ throw new NoSuchAlgorithmException(msg);
+ }
+
+ /**
+ * Create a new key generator from the named provider.
+ *
+ * @param algorithm The generator algorithm name.
+ * @param provider The name of the provider to use.
+ * @return An appropriate key generator, if found.
+ * @throws java.security.NoSuchAlgorithmException If the specified
+ * algorithm is not implemented by the named provider.
+ * @throws java.security.NoSuchProviderException If the named provider
+ * does not exist.
+ */
+ public static final KeyGenerator getInstance(String algorithm, String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ Provider p = Security.getProvider(provider);
+ if (p == null)
+ {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(algorithm, p);
+ }
+
+ /**
+ * Create a new key generator from the supplied provider.
+ *
+ * @param algorithm The generator algorithm name.
+ * @param provider The provider to use.
+ * @return An appropriate key generator, if found.
+ * @throws java.security.NoSuchAlgorithmException If the specified
+ * algorithm is not implemented by the provider.
+ */
+ public static final KeyGenerator getInstance(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ try
+ {
+ return new KeyGenerator((KeyGeneratorSpi)
+ Engine.getInstance(SERVICE, algorithm, provider),
+ provider, algorithm);
+ }
+ catch (InvocationTargetException ite)
+ {
+ if (ite.getCause() == null)
+ throw new NoSuchAlgorithmException(algorithm);
+ if (ite.getCause() instanceof NoSuchAlgorithmException)
+ throw (NoSuchAlgorithmException) ite.getCause();
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+ catch (ClassCastException cce)
+ {
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Generate a key.
+ *
+ * @return The new key.
+ */
+ public final SecretKey generateKey()
+ {
+ return kgSpi.engineGenerateKey();
+ }
+
+ /**
+ * Return the name of this key generator.
+ *
+ * @return The algorithm name.
+ */
+ public final String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * Return the provider of the underlying implementation.
+ *
+ * @return The provider.
+ */
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Initialize this key generator with a set of parameters; the
+ * highest-priority {@link java.security.SecureRandom} implementation
+ * will be used.
+ *
+ * @param params The algorithm parameters.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * supplied parameters are inapproprate.
+ */
+ public final void init(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException
+ {
+ init(params, new SecureRandom());
+ }
+
+ /**
+ * Initialize this key generator with a set of parameters and a source
+ * of randomness.
+ *
+ * @param params The algorithm parameters.
+ * @param random The source of randomness.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * supplied parameters are inapproprate.
+ */
+ public final void init(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ kgSpi.engineInit(params, random);
+ }
+
+ /**
+ * Initialize this key generator with a key size (in bits); the
+ * highest-priority {@link java.security.SecureRandom} implementation
+ * will be used.
+ *
+ * @param keySize The target key size, in bits.
+ * @throws java.security.InvalidParameterException If the
+ * key size is unsupported.
+ */
+ public final void init(int keySize)
+ {
+ init(keySize, new SecureRandom());
+ }
+
+ /**
+ * Initialize this key generator with a key size (in bits) and a
+ * source of randomness.
+ *
+ * @param keySize The target key size, in bits.
+ * @param random The source of randomness.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * key size is unsupported.
+ */
+ public final void init(int keySize, SecureRandom random)
+ {
+ kgSpi.engineInit(keySize, random);
+ }
+
+ /**
+ * Initialize this key generator with a source of randomness. The
+ * implementation-specific default parameters (such as key size) will
+ * be used.
+ *
+ * @param random The source of randomness.
+ */
+ public final void init(SecureRandom random)
+ {
+ kgSpi.engineInit(random);
+ }
+}
diff --git a/libjava/javax/crypto/KeyGeneratorSpi.java b/libjava/javax/crypto/KeyGeneratorSpi.java
new file mode 100644
index 00000000000..fcf229b955c
--- /dev/null
+++ b/libjava/javax/crypto/KeyGeneratorSpi.java
@@ -0,0 +1,112 @@
+/* KeyGeneratorSpi.java -- The key generator service provider interface.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The Service Provider Interface (SPI) for the {@link
+ * KeyGenerator} class.
+ *
+ * "KeyGenerator").
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see KeyGenerator
+ */
+public abstract class KeyGeneratorSpi
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /** Create a new key generator SPI. */
+ public KeyGeneratorSpi()
+ {
+ }
+
+ // Abstract instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Generate a key, returning it as a {@link SecretKey}.
+ *
+ * @return The generated key.
+ */
+ protected abstract SecretKey engineGenerateKey();
+
+ /**
+ * Initialize this key generator with parameters and a source of
+ * randomness.
+ *
+ * @param params The parameters.
+ * @param random The source of randomness.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * parameters are inappropriate for this instance.
+ */
+ protected abstract void engineInit(AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException;
+
+ /**
+ * Initialize this key generator with a key size (in bits) and a
+ * source of randomness.
+ *
+ * @param keySize The target key size, in bits.
+ * @param random The source of randomness.
+ * @throws java.security.InvalidParameterException If the
+ * key size is illogical or unsupported.
+ */
+ protected abstract void engineInit(int keySize, SecureRandom random);
+
+ /**
+ * Initialize this key generator with a source of randomness; the
+ * implementation should use reasonable default parameters (such as
+ * generated key size).
+ *
+ * @param random The source of randomness.
+ */
+ protected abstract void engineInit(SecureRandom random);
+}
diff --git a/libjava/javax/crypto/Mac.java b/libjava/javax/crypto/Mac.java
new file mode 100644
index 00000000000..55f5be61b17
--- /dev/null
+++ b/libjava/javax/crypto/Mac.java
@@ -0,0 +1,414 @@
+/* Mac.java -- The message authentication code interface.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.lang.reflect.InvocationTargetException;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+
+import gnu.java.security.Engine;
+
+/**
+ * This class implements a "message authentication code" (MAC), a method
+ * to ensure the integrity of data transmitted between two parties who
+ * share a common secret key.
+ *
+ *
+ *
+ * D = MAC(K, M)K is the key, M is the message,
+ * and D is the resulting digest. One party will usually
+ * send the concatenation M || D to the other party, who
+ * will then verify D by computing D' in a
+ * similar fashion. If D == D', then the message is assumed
+ * to be authentic.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class Mac implements Cloneable
+{
+
+ // Fields.
+ // ------------------------------------------------------------------------
+
+ private static final String SERVICE = "Mac";
+
+ /** The underlying MAC implementation. */
+ private MacSpi macSpi;
+
+ /** The provider we got our implementation from. */
+ private Provider provider;
+
+ /** The name of the algorithm. */
+ private String algorithm;
+
+ /** Whether or not we've been initialized. */
+ private boolean virgin;
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Creates a new Mac instance.
+ *
+ * @param macSpi The underlying MAC implementation.
+ * @param provider The provider of this implementation.
+ * @param algorithm The name of this MAC algorithm.
+ */
+ protected Mac(MacSpi macSpi, Provider provider, String algorithm)
+ {
+ this.macSpi = macSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
+ virgin = true;
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get an instance of the named algorithm from the first provider with
+ * an appropriate implementation.
+ *
+ * @param algorithm The name of the algorithm.
+ * @return An appropriate Mac instance, if the specified algorithm
+ * is implemented by a provider.
+ * @throws java.security.NoSuchAlgorithmException If no implementation
+ * of the named algorithm is installed.
+ */
+ public static final Mac getInstance(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] provs = Security.getProviders();
+ String msg = "";
+ for (int i = 0; i < provs.length; i++)
+ {
+ try
+ {
+ return getInstance(algorithm, provs[i]);
+ }
+ catch (NoSuchAlgorithmException nsae)
+ {
+ msg = nsae.getMessage();
+ }
+ }
+ throw new NoSuchAlgorithmException(msg);
+ }
+
+ /**
+ * Get an instance of the named algorithm from the named provider.
+ *
+ * @param algorithm The name of the algorithm.
+ * @param provider The name of the provider.
+ * @return An appropriate Mac instance, if the specified algorithm is
+ * implemented by the named provider.
+ * @throws java.security.NoSuchAlgorithmException If the named provider
+ * has no implementation of the algorithm.
+ * @throws java.security.NoSuchProviderException If the named provider
+ * does not exist.
+ */
+ public static final Mac getInstance(String algorithm, String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ Provider p = Security.getProvider(provider);
+ if (p == null)
+ {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(algorithm, p);
+ }
+
+ /**
+ * Get an instance of the named algorithm from a provider.
+ *
+ * @param algorithm The name of the algorithm.
+ * @param provider The provider.
+ * @return An appropriate Mac instance, if the specified algorithm is
+ * implemented by the provider.
+ * @throws java.security.NoSuchAlgorithmException If the provider
+ * has no implementation of the algorithm.
+ */
+ public static final Mac getInstance(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ try
+ {
+ return new Mac((MacSpi) Engine.getInstance(SERVICE, algorithm, provider),
+ provider, algorithm);
+ }
+ catch (InvocationTargetException ite)
+ {
+ if (ite.getCause() == null)
+ throw new NoSuchAlgorithmException(algorithm);
+ if (ite.getCause() instanceof NoSuchAlgorithmException)
+ throw (NoSuchAlgorithmException) ite.getCause();
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+ catch (ClassCastException cce)
+ {
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Finishes the computation of a MAC and returns the digest.
+ *
+ * init, and can compute another MAC using the
+ * same key and parameters.
+ *
+ * @return The message authentication code.
+ * @throws java.lang.IllegalStateException If this instnace has not
+ * been initialized.
+ */
+ public final byte[] doFinal() throws IllegalStateException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ byte[] digest = macSpi.engineDoFinal();
+ reset();
+ return digest;
+ }
+
+ /**
+ * Finishes the computation of a MAC with a final byte array (or
+ * computes a MAC over those bytes only) and returns the digest.
+ *
+ * init, and can compute another MAC using the
+ * same key and parameters.
+ *
+ * @param input The bytes to add.
+ * @return The message authentication code.
+ * @throws java.lang.IllegalStateException If this instnace has not
+ * been initialized.
+ */
+ public final byte[] doFinal(byte[] input) throws IllegalStateException
+ {
+ update(input);
+ byte[] digest = macSpi.engineDoFinal();
+ reset();
+ return digest;
+ }
+
+ /**
+ * Finishes the computation of a MAC and places the result into the
+ * given array.
+ *
+ * init, and can compute another MAC using the
+ * same key and parameters.
+ *
+ * @param output The destination for the result.
+ * @param outOffset The index in the output array to start.
+ * @return The message authentication code.
+ * @throws java.lang.IllegalStateException If this instnace has not
+ * been initialized.
+ * @throws javax.crypto.ShortBufferException If output is
+ * not large enough to hold the result.
+ */
+ public final void doFinal(byte[] output, int outOffset)
+ throws IllegalStateException, ShortBufferException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ if (output.length - outOffset < getMacLength())
+ {
+ throw new ShortBufferException();
+ }
+ byte[] mac = macSpi.engineDoFinal();
+ System.arraycopy(mac, 0, output, outOffset, getMacLength());
+ reset();
+ }
+
+ /**
+ * Returns the name of this MAC algorithm.
+ *
+ * @return The MAC name.
+ */
+ public final String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * Get the size of the MAC. This is the size of the array returned by
+ * {@link #doFinal()} and {@link #doFinal(byte[])}, and the minimum
+ * number of bytes that must be available in the byte array passed to
+ * {@link #doFinal(byte[],int)}.
+ *
+ * @return The MAC length.
+ */
+ public int getMacLength()
+ {
+ return macSpi.engineGetMacLength();
+ }
+
+ /**
+ * Get the provider of the underlying implementation.
+ *
+ * @return The provider.
+ */
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Initialize this MAC with a key and no parameters.
+ *
+ * @param key The key to initialize this instance with.
+ * @throws java.security.InvalidKeyException If the key is
+ * unacceptable.
+ */
+ public final void init(Key key) throws InvalidKeyException
+ {
+ try
+ {
+ init(key, null);
+ }
+ catch (InvalidAlgorithmParameterException iape)
+ {
+ throw new IllegalArgumentException(algorithm + " needs parameters");
+ }
+ }
+
+ /**
+ * Initialize this MAC with a key and parameters.
+ *
+ * @param key The key to initialize this instance with.
+ * @param params The algorithm-specific parameters.
+ * @throws java.security.InvalidAlgorithmParameterException If the
+ * algorithm parameters are unacceptable.
+ * @throws java.security.InvalidKeyException If the key is
+ * unacceptable.
+ */
+ public final void init(Key key, AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException, InvalidKeyException
+ {
+ macSpi.engineInit(key, params);
+ virgin = false; // w00t!
+ }
+
+ /**
+ * Reset this instance. A call to this method returns this instance
+ * back to the state it was in just after it was initialized.
+ */
+ public final void reset()
+ {
+ macSpi.engineReset();
+ }
+
+ /**
+ * Update the computation with a single byte.
+ *
+ * @param input The next byte.
+ * @throws java.lang.IllegalStateException If this instance has not
+ * been initialized.
+ */
+ public final void update(byte input) throws IllegalStateException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ macSpi.engineUpdate(input);
+ }
+
+ /**
+ * Update the computation with a byte array.
+ *
+ * @param input The next bytes.
+ * @throws java.lang.IllegalStateException If this instance has not
+ * been initialized.
+ */
+ public final void update(byte[] input) throws IllegalStateException
+ {
+ update(input, 0, input.length);
+ }
+
+ /**
+ * Update the computation with a portion of a byte array.
+ *
+ * @param input The next bytes.
+ * @param offset The index in input to start.
+ * @param length The number of bytes to update.
+ * @throws java.lang.IllegalStateException If this instance has not
+ * been initialized.
+ */
+ public final void update(byte[] input, int offset, int length)
+ throws IllegalStateException
+ {
+ if (virgin)
+ {
+ throw new IllegalStateException("not initialized");
+ }
+ macSpi.engineUpdate(input, offset, length);
+ }
+
+ /**
+ * Clone this instance, if the underlying implementation supports it.
+ *
+ * @return A clone of this instance.
+ * @throws java.lang.CloneNotSupportedException If the underlying
+ * implementation is not cloneable.
+ */
+ public Object clone() throws CloneNotSupportedException
+ {
+ Mac result = new Mac((MacSpi) macSpi.clone(), provider, algorithm);
+ result.virgin = virgin;
+ return result;
+ }
+}
diff --git a/libjava/javax/crypto/MacSpi.java b/libjava/javax/crypto/MacSpi.java
new file mode 100644
index 00000000000..3bee392f49d
--- /dev/null
+++ b/libjava/javax/crypto/MacSpi.java
@@ -0,0 +1,145 @@
+/* MacSpi.java -- The MAC service provider interface.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * This is the Service Provider Interface (SPI) for the
+ * {@link Mac} class.
+ *
+ * input at which to start.
+ * @param length The number of bytes to update.
+ */
+ protected abstract void engineUpdate(byte[] input, int offset, int length);
+}
diff --git a/libjava/javax/crypto/NoSuchPaddingException.java b/libjava/javax/crypto/NoSuchPaddingException.java
new file mode 100644
index 00000000000..3acd7ae68f6
--- /dev/null
+++ b/libjava/javax/crypto/NoSuchPaddingException.java
@@ -0,0 +1,71 @@
+/* NoSuchPaddingException.java -- Signals an unknown padding scheme.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * This exception is thrown when a particular padding scheme is
+ * requested but is not available.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class NoSuchPaddingException extends GeneralSecurityException
+{
+
+ // Constant.
+ // ------------------------------------------------------------------------
+
+ /** Serialization constant. */
+ private static final long serialVersionUID = -4572885201200175466L;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ public NoSuchPaddingException()
+ {
+ super();
+ }
+
+ public NoSuchPaddingException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/crypto/NullCipher.java b/libjava/javax/crypto/NullCipher.java
new file mode 100644
index 00000000000..95f3a8e8f2d
--- /dev/null
+++ b/libjava/javax/crypto/NullCipher.java
@@ -0,0 +1,62 @@
+/* NullCipher.java -- The identity cipher.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+/**
+ * Trivial subclass of Cipher that implements the identity
+ * transformation, where the input is always copied to the output
+ * unchanged. Null ciphers can be instantiated with the public
+ * constructor.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class NullCipher extends Cipher
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new identity cipher.
+ */
+ public NullCipher()
+ {
+ super(new NullCipherImpl(), null, "NULL");
+ }
+}
diff --git a/libjava/javax/crypto/NullCipherImpl.java b/libjava/javax/crypto/NullCipherImpl.java
new file mode 100644
index 00000000000..b203d24bf78
--- /dev/null
+++ b/libjava/javax/crypto/NullCipherImpl.java
@@ -0,0 +1,127 @@
+/* NullCipherImpl.java -- implementation of NullCipher.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.Key;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * Implementation of the identity cipher.
+ */
+final class NullCipherImpl extends CipherSpi
+{
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ NullCipherImpl()
+ {
+ super();
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ protected void engineSetMode(String mode) { }
+ protected void engineSetPadding(String padding) { }
+
+ protected int engineGetBlockSize()
+ {
+ return 1;
+ }
+
+ protected int engineGetOutputSize(int inputLen)
+ {
+ return inputLen;
+ }
+
+ protected byte[] engineGetIV()
+ {
+ return null;
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
+ protected void engineInit(int mode, Key key, SecureRandom random) { }
+ protected void engineInit(int mode, Key key, AlgorithmParameterSpec spec, SecureRandom random) { }
+ protected void engineInit(int mode, Key key, AlgorithmParameters params, SecureRandom random) { }
+
+ protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen)
+ {
+ if (input == null)
+ return new byte[0];
+ if (inputOffset < 0 || inputLen < 0 || inputOffset + inputLen > input.length)
+ throw new ArrayIndexOutOfBoundsException();
+ byte[] output = new byte[inputLen];
+ System.arraycopy(input, inputOffset, output, 0, inputLen);
+ return output;
+ }
+
+ protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException
+ {
+ if (input == null)
+ return 0;
+ if (inputOffset < 0 || inputLen < 0 || inputOffset + inputLen > input.length
+ || outputOffset < 0)
+ throw new ArrayIndexOutOfBoundsException();
+ if (output.length - outputOffset < inputLen)
+ throw new ShortBufferException();
+ System.arraycopy(input, inputOffset, output, outputOffset, inputLen);
+ return inputLen;
+ }
+
+ protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+ {
+ return engineUpdate(input, inputOffset, inputLen);
+ }
+
+ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException
+ {
+ return engineUpdate(input, inputOffset, inputLen, output, outputOffset);
+ }
+}
diff --git a/libjava/javax/crypto/SealedObject.java b/libjava/javax/crypto/SealedObject.java
new file mode 100644
index 00000000000..9bbbe29be01
--- /dev/null
+++ b/libjava/javax/crypto/SealedObject.java
@@ -0,0 +1,355 @@
+/* SealedObject.java -- An encrypted Serializable object.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+
+/**
+ * This class allows any {@link java.io.Serializable} object to be
+ * stored in an encrypted form.
+ *
+ *
+ *
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class SealedObject implements Serializable
+{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------------
+
+ /** The encoded algorithm parameters. */
+ protected byte[] encodedParams;
+
+ /** The serialized, encrypted object. */
+ private byte[] encryptedContent;
+
+ /** The algorithm used to seal the object. */
+ private String sealAlg;
+
+ /** The parameter type. */
+ private String paramsAlg;
+
+ /** The cipher that decrypts when this object is unsealed. */
+ private transient Cipher sealCipher;
+
+ /** Compatible with JDK1.4. */
+ private static final long serialVersionUID = 4482838265551344752L;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new sealed object from a {@link java.io.Serializable}
+ * object and a cipher.
+ *
+ * @param object The object to seal.
+ * @param cipher The cipher to encrypt with.
+ * @throws java.io.IOException If serializing the object fails.
+ * @throws javax.crypto.IllegalBlockSizeException If the cipher has no
+ * padding and the size of the serialized representation of the
+ * object is not a multiple of the cipher's block size.
+ */
+ public SealedObject(Serializable object, Cipher cipher)
+ throws IOException, IllegalBlockSizeException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(object);
+ oos.flush();
+ try
+ {
+ encryptedContent = cipher.doFinal(baos.toByteArray());
+ }
+ catch (IllegalStateException ise)
+ {
+ throw new IOException("cipher not in proper state");
+ }
+ catch (BadPaddingException bpe)
+ {
+ throw new IOException(
+ "encrypting but got javax.crypto.BadPaddingException");
+ }
+ sealAlg = cipher.getAlgorithm();
+ encodedParams = cipher.getParameters().getEncoded();
+ paramsAlg = cipher.getParameters().getAlgorithm();
+ }
+
+ /**
+ * Create a new sealed object from another sealed object.
+ *
+ * @param so The other sealed object.
+ */
+ protected SealedObject(SealedObject so)
+ {
+ this.encodedParams = (byte[]) so.encodedParams.clone();
+ this.encryptedContent = (byte[]) so.encryptedContent.clone();
+ this.sealAlg = so.sealAlg;
+ this.paramsAlg = so.paramsAlg;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the name of the algorithm used to seal this object.
+ *
+ * @return The algorithm's name.
+ */
+ public final String getAlgorithm()
+ {
+ return sealAlg;
+ }
+
+ /**
+ * Unseal and deserialize this sealed object with a specified (already
+ * initialized) cipher.
+ *
+ * @param cipher The cipher to decrypt with.
+ * @return The original object.
+ * @throws java.io.IOException If reading fails.
+ * @throws java.lang.ClassNotFoundException If deserialization fails.
+ * @throws javax.crypto.IllegalBlockSizeException If the cipher has no
+ * padding and the encrypted data is not a multiple of the
+ * cipher's block size.
+ * @throws javax.crypto.BadPaddingException If the padding bytes are
+ * incorrect.
+ */
+ public final Object getObject(Cipher cipher)
+ throws IOException, ClassNotFoundException, IllegalBlockSizeException,
+ BadPaddingException
+ {
+ sealCipher = cipher;
+ return unseal();
+ }
+
+ /**
+ * Unseal and deserialize this sealed object with the specified key.
+ *
+ * @param key The key to decrypt with.
+ * @return The original object.
+ * @throws java.io.IOException If reading fails.
+ * @throws java.lang.ClassNotFoundException If deserialization fails.
+ * @throws java.security.InvalidKeyException If the supplied key
+ * cannot be used to unseal this object.
+ * @throws java.security.NoSuchAlgorithmException If the algorithm
+ * used to originally seal this object is not available.
+ */
+ public final Object getObject(Key key)
+ throws IOException, ClassNotFoundException, InvalidKeyException,
+ NoSuchAlgorithmException
+ {
+ try
+ {
+ if (sealCipher == null)
+ sealCipher = Cipher.getInstance(sealAlg);
+ }
+ catch (NoSuchPaddingException nspe)
+ {
+ throw new NoSuchAlgorithmException(nspe.getMessage());
+ }
+ AlgorithmParameters params = null;
+ if (encodedParams != null)
+ {
+ params = AlgorithmParameters.getInstance(paramsAlg);
+ params.init(encodedParams);
+ }
+ try
+ {
+ sealCipher.init(Cipher.DECRYPT_MODE, key, params);
+ return unseal();
+ }
+ catch (InvalidAlgorithmParameterException iape)
+ {
+ throw new IOException("bad parameters");
+ }
+ catch (IllegalBlockSizeException ibse)
+ {
+ throw new IOException("illegal block size");
+ }
+ catch (BadPaddingException bpe)
+ {
+ throw new IOException("bad padding");
+ }
+ }
+
+ /**
+ * Unseal and deserialize this sealed object with the specified key,
+ * using a cipher from the named provider.
+ *
+ * @param key The key to decrypt with.
+ * @param provider The name of the provider to use.
+ * @return The original object.
+ * @throws java.io.IOException If reading fails.
+ * @throws java.lang.ClassNotFoundException If deserialization fails.
+ * @throws java.security.InvalidKeyException If the supplied key
+ * cannot be used to unseal this object.
+ * @throws java.security.NoSuchAlgorithmException If the algorithm
+ * used to originally seal this object is not available from
+ * the named provider.
+ * @throws java.security.NoSuchProviderException If the named provider
+ * does not exist.
+ */
+ public final Object getObject(Key key, String provider)
+ throws IOException, ClassNotFoundException, InvalidKeyException,
+ NoSuchAlgorithmException, NoSuchProviderException
+ {
+ try
+ {
+ sealCipher = Cipher.getInstance(sealAlg, provider);
+ }
+ catch (NoSuchPaddingException nspe)
+ {
+ throw new NoSuchAlgorithmException(nspe.getMessage());
+ }
+ AlgorithmParameters params = null;
+ if (encodedParams != null)
+ {
+ params = AlgorithmParameters.getInstance(paramsAlg, provider);
+ params.init(encodedParams);
+ }
+ try
+ {
+ sealCipher.init(Cipher.DECRYPT_MODE, key, params);
+ return unseal();
+ }
+ catch (InvalidAlgorithmParameterException iape)
+ {
+ throw new IOException("bad parameters");
+ }
+ catch (IllegalBlockSizeException ibse)
+ {
+ throw new IOException("illegal block size");
+ }
+ catch (BadPaddingException bpe)
+ {
+ throw new IOException("bad padding");
+ }
+ }
+
+ // Own methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Deserialize this object.
+ *
+ * @param ois The input stream.
+ * @throws java.io.IOException If reading fails.
+ * @throws java.lang.ClassNotFoundException If reading fails.
+ */
+ private void readObject(ObjectInputStream ois)
+ throws IOException, ClassNotFoundException
+ {
+ encodedParams = (byte[]) ois.readObject();
+ encryptedContent = (byte[]) ois.readObject();
+ sealAlg = (String) ois.readObject();
+ paramsAlg = (String) ois.readObject();
+ }
+
+ /**
+ * Serialize this object.
+ *
+ * @param oos The output stream.
+ * @throws java.io.IOException If writing fails.
+ */
+ private void writeObject(ObjectOutputStream oos)
+ throws IOException
+ {
+ oos.writeObject(encodedParams);
+ oos.writeObject(encryptedContent);
+ oos.writeObject(sealAlg);
+ oos.writeObject(paramsAlg);
+ }
+
+ /**
+ * Unseal this object, returning it.
+ *
+ * @return The unsealed, deserialized Object.
+ * @throws java.io.IOException If reading fails.
+ * @throws java.io.ClassNotFoundException If reading fails.
+ * @throws javax.crypto.IllegalBlockSizeException If the cipher has no
+ * padding and the encrypted data is not a multiple of the
+ * cipher's block size.
+ * @throws javax.crypto.BadPaddingException If the padding bytes are
+ * incorrect.
+ */
+ private Object unseal()
+ throws IOException, ClassNotFoundException, IllegalBlockSizeException,
+ BadPaddingException
+ {
+ ByteArrayInputStream bais = null;
+ try
+ {
+ bais = new ByteArrayInputStream(sealCipher.doFinal(encryptedContent));
+ }
+ catch (IllegalStateException ise)
+ {
+ throw new IOException("cipher not initialized");
+ }
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ return ois.readObject();
+ }
+}
diff --git a/libjava/javax/crypto/SecretKey.java b/libjava/javax/crypto/SecretKey.java
new file mode 100644
index 00000000000..85529b94de2
--- /dev/null
+++ b/libjava/javax/crypto/SecretKey.java
@@ -0,0 +1,67 @@
+/* SecretKey.java -- A key for symmetric cryptography.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License along
+with GNU Classpath; if not, write to the
+
+ Free Software Foundation, Inc.,
+ 59 Temple Place, Suite 330,
+ Boston, MA 02111-1307
+ USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under terms
+of your choice, provided that you also meet, for each linked independent
+module, the terms and conditions of the license of that module. An
+independent module is a module which is not derived from or based on
+this library. If you modify this library, you may extend this exception
+to your version of the library, but you are not obligated to do so. If
+you do not wish to do so, delete this exception statement from your
+version. */
+
+
+package javax.crypto;
+
+import java.security.Key;
+
+/**
+ * A secret key for symmetric cryptography.
+ *
+ *
+ *
+ * or,RAW, as returned
+ * by {@link java.security.Key#getFormat()}."SecretKeyFactory").
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see SecretKeyFactory
+ */
+public abstract class SecretKeyFactorySpi
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new secret key factory SPI.
+ */
+ public SecretKeyFactorySpi()
+ {
+ }
+
+ // Abstract instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Translate a {@link java.security.KeySpec} into a {@link SecretKey}.
+ *
+ * @param keySpec The key specification.
+ * @return The secret key.
+ * @throws java.security.spec.InvalidKeySpecException If the key specification
+ * cannot be translated into a secret key.
+ */
+ protected abstract SecretKey engineGenerateSecret(KeySpec keySpec)
+ throws InvalidKeySpecException;
+
+ /**
+ * Translate a {@link SecretKey} into a {@link java.security.KeySpec}.
+ *
+ * @param key The secret key.
+ * @param keySpec The desired key specification class.
+ * @return The key specification.
+ * @throws java.security.spec.InvalidKeySpecException If the secret key cannot
+ * be translated into the desired key specification.
+ */
+ protected abstract KeySpec engineGetKeySpec(SecretKey key, Class keySpec)
+ throws InvalidKeySpecException;
+
+ /**
+ * Translate a secret key into a different representation.
+ *
+ * @param key The secret key to translate.
+ * @return The translated key.
+ * @throws java.security.InvalidKeyException If the specified secret
+ * key cannot be translated.
+ */
+ protected abstract SecretKey engineTranslateKey(SecretKey key)
+ throws InvalidKeyException;
+}
diff --git a/libjava/javax/crypto/ShortBufferException.java b/libjava/javax/crypto/ShortBufferException.java
new file mode 100644
index 00000000000..5b5bf5437e5
--- /dev/null
+++ b/libjava/javax/crypto/ShortBufferException.java
@@ -0,0 +1,70 @@
+/* ShortBufferException.java -- Signals a short output buffer.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * This exception is thrown on an attempt to transform bytes into a
+ * buffer that is too short to contain the data.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class ShortBufferException extends GeneralSecurityException
+{
+
+ // Constant.
+ // ------------------------------------------------------------------------
+
+ /** Serialization constant. */
+ private static final long serialVersionUID = 8427718640832943747L;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ public ShortBufferException()
+ {
+ super();
+ }
+
+ public ShortBufferException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/crypto/interfaces/DHKey.java b/libjava/javax/crypto/interfaces/DHKey.java
new file mode 100644
index 00000000000..d5d827946df
--- /dev/null
+++ b/libjava/javax/crypto/interfaces/DHKey.java
@@ -0,0 +1,61 @@
+/* DHKey.java -- General interface for a Diffie-Hellman key.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.interfaces;
+
+import javax.crypto.spec.DHParameterSpec;
+
+/**
+ * This interface marks public/private keys in the Diffie-Hellman key
+ * exchange algorithm. Implementations of Diffie-Hellman keys should
+ * implement this interface, and applications can safely cast keys that
+ * are known to be Diffie-Hellman keys to this interface.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public interface DHKey
+{
+ /**
+ * Returns the Diffie-Hellman parameters for this key, which includes
+ * the generator and the prime.
+ *
+ * @return The Diffie-Hellman parameters.
+ */
+ DHParameterSpec getParams();
+}
diff --git a/libjava/javax/crypto/interfaces/DHPrivateKey.java b/libjava/javax/crypto/interfaces/DHPrivateKey.java
new file mode 100644
index 00000000000..63b9c15c416
--- /dev/null
+++ b/libjava/javax/crypto/interfaces/DHPrivateKey.java
@@ -0,0 +1,70 @@
+/* DHPrivateKey.java -- A Diffie-Hellman private key.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.interfaces;
+
+import java.math.BigInteger;
+import java.security.PrivateKey;
+
+/**
+ * This interface marks a private key in the Diffie-Hellman key exchange
+ * algorithm. It should be treated with as much care as any {@link
+ * java.security.PrivateKey}.
+ *
+ * offset in
+ * the byte array. The first 8 bytes starting at offset
+ * are copied.
+ *
+ * @param key The key bytes.
+ * @param offset The offset into the byte array at which to begin.
+ * @throws java.security.InvalidKeyException If there are less than 8
+ * bytes starting at offset.
+ */
+ public DESKeySpec(byte[] key, int offset) throws InvalidKeyException
+ {
+ if (key.length - offset < DES_KEY_LEN)
+ {
+ throw new InvalidKeyException("DES keys must be 8 bytes long");
+ }
+ this.key = new byte[DES_KEY_LEN];
+ System.arraycopy(key, offset, this.key, 0, DES_KEY_LEN);
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns whether or not the given key is parity adjusted;
+ * i.e. every byte in the key has an odd number of "1" bits.
+ *
+ * @param key The key bytes, considered between [offset,
+ * offset+7]
+ * @param offset The offset into the byte array at which to begin.
+ * @return True if all bytes have an odd number of "1" bits.
+ * @throws java.security.InvalidKeyException If there are not enough
+ * bytes in the array.
+ */
+ public static boolean isParityAdjusted(byte[] key, int offset)
+ throws InvalidKeyException
+ {
+ if (key.length - offset < DES_KEY_LEN)
+ {
+ throw new InvalidKeyException("DES keys must be 8 bytes long");
+ }
+ boolean parity = false;
+ boolean oddbits = false;
+ for (int i = 0; i < DES_KEY_LEN; i++)
+ {
+ oddbits = false;
+ for (int j = 0; j < 8; j++)
+ {
+ oddbits ^= (key[i+offset] & 1 << j) != 0;
+ }
+ parity &= oddbits;
+ }
+ return parity;
+ }
+
+ /**
+ * One-half of the weak and semiweak DES keys (the other half are the
+ * complements of these).
+ */
+ private static final byte[][] WEAK_KEYS = new byte[][] {
+ { 0, 0, 0, 0, 0, 0, 0, 0 }, // 0000 0000 0000 0000
+ { -1, -1, -1, -1, 0, 0, 0, 0 }, // ffff ffff 0000 0000
+ { 1, 1, 1, 1, 1, 1, 1, 1 }, // 0101 0101 0101 0101
+ { 31, 31, 31, 31, 14, 14, 14, 14 }, // 1f1f 1f1f 0e0e 0e0e
+ { 1, -2, 1, -2, 1, -2, 1, -2 }, // 01fe 01fe 01fe 01fe
+ { 31, -32, 31, -32, -32, 31, -32, 31 }, // 1fe0 1fe0 0e1f 0e1f
+ { 1, -32, 1, -32, 1, -15, 1, -15 }, // 01e0 01e0 01f1 01f1
+ { 31, -2, 31, -2, 14, -2, 14, -2 }, // 1ffe 1ffe 0efe 0efe
+ { 1, 31, 1, 31, 1, 14, 1, 14 }, // 011f 011f 010e 010e
+ { -32, -2, -32, -2, -15, -2, -15, -2 }, // e0fe e0fe f1fe f1fe
+ };
+
+ /**
+ * Tests if the bytes between [offset, offset+7]
+ * constitute a weak or semi-weak DES key.
+ *
+ * @param key The key bytes to check.
+ * @param offset The offset in the byte array to start.
+ * @return true If the key bytes are a weak key.
+ */
+ public static boolean isWeak(byte[] key, int offset)
+ throws InvalidKeyException
+ {
+ if (key.length - offset < DES_KEY_LEN)
+ {
+ throw new InvalidKeyException("DES keys must be 8 bytes long");
+ }
+ for (int i = 0; i < WEAK_KEYS.length; i++)
+ {
+ if (equalsOrComplementEquals(key, offset, WEAK_KEYS[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * This method returns true if the first 8 bytes starting at
+ * off in a equal the first 8 bytes in
+ * b, or equal the complement of the first 8 bytes
+ * in b.
+ *
+ * @param a The first byte array.
+ * @param off The index into the first byte array.
+ * @param b The second byte array.
+ * @return a == b || a == ~b
+ */
+ private static boolean equalsOrComplementEquals(byte[] a, int off, byte[] b)
+ {
+ boolean result = true;
+ for (int i = 0; i < DES_KEY_LEN; i++)
+ {
+ result &= a[off+i] == b[i];
+ }
+ if (result) return true;
+ result = true;
+ for (int i = 0; i < DES_KEY_LEN; i++)
+ {
+ result &= a[off+i] == (~b[i]);
+ }
+ return result;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Return the key as a byte array. This method does not copy the byte
+ * array.
+ *
+ * @return The key bytes.
+ */
+ public byte[] getKey()
+ {
+ return key;
+ }
+}
diff --git a/libjava/javax/crypto/spec/DESedeKeySpec.java b/libjava/javax/crypto/spec/DESedeKeySpec.java
new file mode 100644
index 00000000000..d455163bcee
--- /dev/null
+++ b/libjava/javax/crypto/spec/DESedeKeySpec.java
@@ -0,0 +1,151 @@
+/* DESedeKeySpec.java -- Keys for triple-DES.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.InvalidKeyException;
+import java.security.spec.KeySpec;
+
+/**
+ * This class is a transparent wrapper for DES-EDE (Triple-DES) keys,
+ * which are arrays of 24 bytes.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class DESedeKeySpec implements KeySpec
+{
+
+ // Constants.
+ // ------------------------------------------------------------------------
+
+ /**
+ * The length of a triple-DES key, in bytes.
+ */
+ public static final int DES_EDE_KEY_LEN = 24;
+
+ /**
+ * The key bytes.
+ */
+ private byte[] key;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new DES-EDE key spec, copying the first 24 bytes from the
+ * byte array.
+ *
+ * @param key The key bytes.
+ * @throws java.security.InvalidKeyException If there are less than 24
+ * bytes in the array.
+ */
+ public DESedeKeySpec(byte[] key) throws InvalidKeyException
+ {
+ this(key, 0);
+ }
+
+ /**
+ * Create a new DES-EDE key spec, starting at offset in
+ * the byte array. The first 24 bytes starting at offset
+ * are copied.
+ *
+ * @param key The key bytes.
+ * @param offset The offset into the byte array at which to begin.
+ * @throws java.security.InvalidKeyException If there are less than 24
+ * bytes starting at offset.
+ */
+ public DESedeKeySpec(byte[] key, int offset) throws InvalidKeyException
+ {
+ if (key.length - offset < DES_EDE_KEY_LEN)
+ {
+ throw new InvalidKeyException("DES-EDE keys must be 24 bytes long");
+ }
+ this.key = new byte[DES_EDE_KEY_LEN];
+ System.arraycopy(key, offset, this.key, 0, DES_EDE_KEY_LEN);
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns whether or not the given key is parity adjusted;
+ * i.e. every byte in the key has an odd number of "1" bits.
+ *
+ * @param key The key bytes, considered between [offset,
+ * offset+23]
+ * @param offset The offset into the byte array at which to begin.
+ * @return True if all bytes have an odd number of "1" bits.
+ * @throws java.security.InvalidKeyException If there are not enough
+ * bytes in the array.
+ */
+ public static boolean isParityAdjusted(byte[] key, int offset)
+ throws InvalidKeyException
+ {
+ if (key.length - offset < DES_EDE_KEY_LEN)
+ {
+ throw new InvalidKeyException("DES-EDE keys must be 24 bytes long");
+ }
+ boolean parity = false;
+ boolean oddbits = false;
+ for (int i = 0; i < DES_EDE_KEY_LEN; i++)
+ {
+ oddbits = false;
+ for (int j = 0; j < 8; j++)
+ {
+ oddbits ^= (key[i+offset] & 1 << j) != 0;
+ }
+ parity &= oddbits;
+ }
+ return parity;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Return the key as a byte array. This method does not copy the byte
+ * array.
+ *
+ * @return The key bytes.
+ */
+ public byte[] getKey()
+ {
+ return key;
+ }
+}
diff --git a/libjava/javax/crypto/spec/DHGenParameterSpec.java b/libjava/javax/crypto/spec/DHGenParameterSpec.java
new file mode 100644
index 00000000000..67392a50f1b
--- /dev/null
+++ b/libjava/javax/crypto/spec/DHGenParameterSpec.java
@@ -0,0 +1,100 @@
+/* DHGenParameterSpec.java -- Diffie-Hellman parameter generator spec.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * This class represents the parameters needed for generating
+ * Diffie-Hellman parameters.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see DHParameterSpec
+ */
+public class DHGenParameterSpec implements AlgorithmParameterSpec
+{
+
+ // Variables.
+ // ------------------------------------------------------------------------
+
+ /** The length of the prime, in bits. */
+ private int primeSize;
+
+ /** The length of the exponent, in bits. */
+ private int exponentSize;
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new Diffie-Hellman parameter generator spec.
+ *
+ * @param primeSize The size of the prime, in bits.
+ * @param exponentSize The size of the exponent, in bits.
+ */
+ public DHGenParameterSpec(int primeSize, int exponentSize)
+ {
+ this.primeSize = primeSize;
+ this.exponentSize = exponentSize;
+ }
+
+ // Intance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the size of the exponent, in bits.
+ *
+ * @return The exponent size.
+ */
+ public int getExponentSize()
+ {
+ return exponentSize;
+ }
+
+ /**
+ * Get the size of the prime, in bits.
+ *
+ * @return The prime size.
+ */
+ public int getPrimeSize()
+ {
+ return primeSize;
+ }
+}
diff --git a/libjava/javax/crypto/spec/DHParameterSpec.java b/libjava/javax/crypto/spec/DHParameterSpec.java
new file mode 100644
index 00000000000..e66f632e882
--- /dev/null
+++ b/libjava/javax/crypto/spec/DHParameterSpec.java
@@ -0,0 +1,135 @@
+/* DHParameterSpec.java -- Parameters for Diffie-Hellman keys.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The base set of parameters necessary to perform Diffie-Hellman key
+ * exchange. Each party in the key exchange shares these parameters.
+ *
+ * g, a prime modulus p, and an
+ * optional length, in bits, of the private exponent.
+ *
+ *
+ *
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ * @see javax.crypto.SecretKeyFactory
+ * @see PBEParameterSpec
+ */
+public class PBEKeySpec implements KeySpec
+{
+
+ // Fields.
+ // ------------------------------------------------------------------------
+
+ /** The iteration count. */
+ private int iterationCount;
+
+ /** The generated key length. */
+ private int keyLength;
+
+ /** The password. */
+ private char[] password;
+
+ /** The salt. */
+ private byte[] salt;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new PBE key spec with just a password.
+ *
+ * @param password The password char array.
+ */
+ public PBEKeySpec(char[] password)
+ {
+ this(password, null, 0, 0);
+ }
+
+ /**
+ * Create a PBE key spec with a password, salt, and iteration count.
+ *
+ * @param password The password char array.
+ * @param salt The salt bytes.
+ * @param iterationCount The iteration count.
+ */
+ public PBEKeySpec(char[] password, byte[] salt, int iterationCount)
+ {
+ this(password, salt, iterationCount, 0);
+ }
+
+ /**
+ * Create a PBE key spec with a password, salt, iteration count, and
+ * key length.
+ *
+ * @param password The password char array.
+ * @param salt The salt bytes.
+ * @param iterationCount The iteration count.
+ * @param keyLength The generated key length.
+ */
+ public PBEKeySpec(char[] password, byte[] salt, int iterationCount,
+ int keyLength)
+ {
+ this.password = password;
+ this.salt = salt;
+ this.iterationCount = iterationCount;
+ this.keyLength = keyLength;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Clear the password array by filling it with null characters.
+ */
+ public final void clearPassword()
+ {
+ if (password == null) return;
+ for (int i = 0; i < password.length; i++)
+ {
+ password[i] = '\u0000';
+ }
+ }
+
+ /**
+ * Get the iteration count, or 0 if it has not been specified.
+ *
+ * @return The iteration count, or 0 if it has not been specified.
+ */
+ public final int getIterationCount()
+ {
+ return iterationCount;
+ }
+
+ /**
+ * Get the generated key length, or 0 if it has not been specified.
+ *
+ * @return The key length, or 0 if it has not been specified.
+ */
+ public final int getKeyLength()
+ {
+ return keyLength;
+ }
+
+ /**
+ * Get the password character array.
+ *
+ * @return The password.
+ */
+ public final char[] getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * Get the salt bytes.
+ *
+ * @return The salt.
+ */
+ public final byte[] getSalt()
+ {
+ return salt;
+ }
+}
diff --git a/libjava/javax/crypto/spec/PBEParameterSpec.java b/libjava/javax/crypto/spec/PBEParameterSpec.java
new file mode 100644
index 00000000000..f45c866c9d8
--- /dev/null
+++ b/libjava/javax/crypto/spec/PBEParameterSpec.java
@@ -0,0 +1,100 @@
+/* PBEParameterSpec.java -- A wrapper for PBE parameters.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * A wrapper for the parameters used in PKCS #5 -
+ * Password-Based Cryptography Standard.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class PBEParameterSpec implements AlgorithmParameterSpec
+{
+
+ // Fields.
+ // ------------------------------------------------------------------------
+
+ /** The iteration count. */
+ private int iterationCount;
+
+ /** The salt. */
+ private byte[] salt;
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Creates a new password-based encryption parameter specification.
+ *
+ * @param salt The salt.
+ * @param iterationCount The iteration count.
+ */
+ public PBEParameterSpec(byte[] salt, int iterationCount)
+ {
+ this.salt = salt;
+ this.iterationCount = iterationCount;
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the iteration count.
+ *
+ * @return The iteration count.
+ */
+ public int getIterationCount()
+ {
+ return iterationCount;
+ }
+
+ /**
+ * Get the salt.
+ *
+ * @return The salt.
+ */
+ public byte[] getSalt()
+ {
+ return salt;
+ }
+}
diff --git a/libjava/javax/crypto/spec/RC2ParameterSpec.java b/libjava/javax/crypto/spec/RC2ParameterSpec.java
new file mode 100644
index 00000000000..ec9cde71cf1
--- /dev/null
+++ b/libjava/javax/crypto/spec/RC2ParameterSpec.java
@@ -0,0 +1,166 @@
+/* RC2ParameterSpec.java -- Wrapper for RC2 parameters.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * A wrapper for parameters for the RC2
+ * block cipher ("RC" means either "Rivest Cipher" or "Ron's Code",
+ * depending upon who you ask and when).
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class RC2ParameterSpec implements AlgorithmParameterSpec
+{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------------
+
+ /** The length of an RC2 IV, in bytes. */
+ private static final int RC2_IV_LENGTH = 8;
+
+ /** The effective key length, in bits. */
+ private int effectiveKeyBits;
+
+ /** The initialization vector. */
+ private byte[] iv;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create RC2 parameters without an IV.
+ *
+ * @param effectiveKeyBits The number of effective key bits.
+ */
+ public RC2ParameterSpec(int effectiveKeyBits)
+ {
+ this.effectiveKeyBits = effectiveKeyBits;
+ }
+
+ /**
+ * Create RC2 parameters with an IV.
+ *
+ * @param effectiveKeyBits The number of effective key bits.
+ * @param iv The IV; the first eight bytes of this array
+ * are used.
+ */
+ public RC2ParameterSpec(int effectiveKeyBits, byte[] iv)
+ {
+ this(effectiveKeyBits, iv, 0);
+ }
+
+ /**
+ * Create RC2 parameters with an IV.
+ *
+ * @param effectiveKeyBits The number of effective key bits.
+ * @param iv The IV; the first eight bytes of this array
+ * after offset are used.
+ * @param offset From whence to start in the array.
+ */
+ public RC2ParameterSpec(int effectiveKeyBits, byte[] iv, int offset)
+ {
+ if (iv.length - offset < RC2_IV_LENGTH)
+ {
+ throw new IllegalArgumentException("IV too short");
+ }
+ this.effectiveKeyBits = effectiveKeyBits;
+ this.iv = new byte[RC2_IV_LENGTH];
+ System.arraycopy(iv, offset, this.iv, 0, RC2_IV_LENGTH);
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the number of effective key bits.
+ *
+ * @return The numer of effective key bits.
+ */
+ public int getEffectiveKeyBits()
+ {
+ return effectiveKeyBits;
+ }
+
+ /**
+ * Return the initialization vector, or null if none was
+ * specified.
+ *
+ * @return The IV, or null.
+ */
+ public byte[] getIV()
+ {
+ return iv;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ byte[] oiv = ((RC2ParameterSpec) o).getIV();
+ if (iv != oiv)
+ {
+ if (iv == null || oiv == null) return false;
+ if (iv.length != oiv.length) return false;
+ for (int i = 0; i < iv.length; i++)
+ {
+ if (iv[i] != oiv[i])
+ {
+ return false;
+ }
+ }
+ }
+ return effectiveKeyBits == ((RC2ParameterSpec) o).getEffectiveKeyBits();
+ }
+
+ public int hashCode()
+ {
+ int code = effectiveKeyBits;
+ if (iv != null)
+ {
+ for (int i = 0; i < RC2_IV_LENGTH; i++)
+ {
+ code += iv[i];
+ }
+ }
+ return code;
+ }
+}
diff --git a/libjava/javax/crypto/spec/RC5ParameterSpec.java b/libjava/javax/crypto/spec/RC5ParameterSpec.java
new file mode 100644
index 00000000000..e7549dd63fe
--- /dev/null
+++ b/libjava/javax/crypto/spec/RC5ParameterSpec.java
@@ -0,0 +1,202 @@
+/* RC5ParameterSpec.java -- parameters for RC5.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * A wrapper for parameters to the RC5
+ * block cipher.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ * @since 1.4
+ */
+public class RC5ParameterSpec implements AlgorithmParameterSpec
+{
+
+ // Fields.
+ // ------------------------------------------------------------------------
+
+ /** The IV. */
+ private byte[] iv;
+
+ /** The number of rounds. */
+ private int rounds;
+
+ /** The version number. */
+ private int version;
+
+ /** The word size, in bits. */
+ private int wordSize;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create RC5 parameters without an IV.
+ *
+ * @param version The version number.
+ * @param rounds The number of rounds.
+ * @param wordSize The size of a word, in bits.
+ */
+ public RC5ParameterSpec(int version, int rounds, int wordSize)
+ {
+ this.version = version;
+ this.rounds = rounds;
+ this.wordSize = wordSize;
+ }
+
+ /**
+ * Create RC5 parameters with an IV. The bytes in iv in
+ * the range [0, 2*(wordSize/8)-1] are used.
+ *
+ * @param version The version number.
+ * @param rounds The number of rounds.
+ * @param wordSize The size of a word, in bits.
+ * @param iv The IV data.
+ */
+ public RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv)
+ {
+ this(version, rounds, wordSize, iv, 0);
+ }
+
+ /**
+ * Create RC5 parameters with an IV. The bytes in iv in
+ * the range [off, off+2*(wordSize/8)-1] are used.
+ *
+ * @param version The version number.
+ * @param rounds The number of rounds.
+ * @param wordSize The size of a word, in bits.
+ * @param iv The IV data.
+ * @param off From where in the array the IV starts.
+ */
+ public
+ RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv, int off)
+ {
+ this(version, rounds, wordSize);
+ int ivLength = 2 * (wordSize / 8);
+ if (off < 0)
+ throw new IllegalArgumentException();
+ if (iv.length - off < ivLength)
+ {
+ throw new IllegalArgumentException("IV too short");
+ }
+ this.iv = new byte[ivLength];
+ System.arraycopy(iv, off, this.iv, 0, ivLength);
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Return the initializaiton vector, or null if none was
+ * specified.
+ *
+ * @return The IV, or null.
+ */
+ public byte[] getIV()
+ {
+ return iv;
+ }
+
+ /**
+ * Get the number of rounds.
+ *
+ * @return The number of rounds.
+ */
+ public int getRounds()
+ {
+ return rounds;
+ }
+
+ /**
+ * Get the version number.
+ *
+ * @return The version number.
+ */
+ public int getVersion()
+ {
+ return version;
+ }
+
+ /**
+ * Get the word size, in bits.
+ *
+ * @return The word size, in bits.
+ */
+ public int getWordSize()
+ {
+ return wordSize;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ byte[] oiv = ((RC5ParameterSpec) o).getIV();
+ if (iv != oiv)
+ {
+ if (iv == null || oiv == null) return false;
+ if (iv.length != oiv.length) return false;
+ for (int i = 0; i < iv.length; i++)
+ {
+ if (iv[i] != oiv[i])
+ {
+ return false;
+ }
+ }
+ }
+ return rounds == ((RC5ParameterSpec) o).getRounds()
+ && version == ((RC5ParameterSpec) o).getVersion()
+ && wordSize == ((RC5ParameterSpec) o).getWordSize();
+ }
+
+ public int hashCode()
+ {
+ int code = rounds + version + wordSize;
+ if (iv != null)
+ {
+ for (int i = 0; i < iv.length; i++)
+ {
+ code += iv[i];
+ }
+ }
+ return code;
+ }
+}
diff --git a/libjava/javax/crypto/spec/SecretKeySpec.java b/libjava/javax/crypto/spec/SecretKeySpec.java
new file mode 100644
index 00000000000..6d9f4b8feb2
--- /dev/null
+++ b/libjava/javax/crypto/spec/SecretKeySpec.java
@@ -0,0 +1,154 @@
+/* SecretKeySpec.java -- Wrapper for secret keys.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.crypto.spec;
+
+import java.security.spec.KeySpec;
+import javax.crypto.SecretKey;
+
+/**
+ * This is a simple wrapper around a raw byte array, for ciphers that do
+ * not require any key parameters other than the bytes themselves.
+ *
+ * init() methods of {@link
+ * javax.crypto.Cipher}.
+ *
+ * @see javax.crypto.SecretKey
+ * @see javax.crypto.SecretKeyFactory
+ */
+public class SecretKeySpec implements KeySpec, SecretKey
+{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------------
+
+ /** Compatible with JDK1.4. */
+ private static final long serialVersionUID = 6577238317307289933L;
+
+ /** The key bytes. */
+ private byte[] key;
+
+ /** The algorithm's name. */
+ private String algorithm;
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new secret key spec from an entire byte array.
+ *
+ * @param key The key material.
+ * @param algorithm The name of the algorithm using this key.
+ */
+ public SecretKeySpec(byte[] key, String algorithm)
+ {
+ this(key, 0, key.length, algorithm);
+ }
+
+ /**
+ * Create a new secret key spec from part of a byte array.
+ *
+ * @param key The key material.
+ * @param off The offset at which key material begins.
+ * @param len The length of key material.
+ * @param algorithm The name of the algorithm using this key.
+ */
+ public SecretKeySpec(byte[] key, int off, int len, String algorithm)
+ {
+ this.key = new byte[len];
+ this.algorithm = algorithm;
+ System.arraycopy(key, off, this.key, 0, len);
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Return the name of the algorithm associated with this secret key.
+ *
+ * @return The algorithm's name.
+ */
+ public String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * Return the key as a byte array.
+ *
+ * @return The key material.
+ */
+ public byte[] getEncoded()
+ {
+ return key;
+ }
+
+ /**
+ * This key's format, which is always "RAW".
+ *
+ * @return "RAW"
+ */
+ public String getFormat()
+ {
+ return "RAW";
+ }
+
+ public boolean equals(Object o)
+ {
+ byte[] okey = ((SecretKeySpec) o).getEncoded();
+ if (key.length != okey.length) return false;
+ for (int i = 0; i < key.length; i++)
+ {
+ if (key[i] != okey[i])
+ return false;
+ }
+ return algorithm.equals(((SecretKeySpec) o).getAlgorithm());
+ }
+
+ public int hashCode()
+ {
+ int code = 0;
+ for (int i = 0; i < key.length; i++)
+ {
+ code ^= (key[i] & 0xff) << (i << 3 & 31);
+ }
+ return code ^ algorithm.hashCode();
+ }
+}
diff --git a/libjava/javax/net/ServerSocketFactory.java b/libjava/javax/net/ServerSocketFactory.java
new file mode 100644
index 00000000000..d20c7fbe9f2
--- /dev/null
+++ b/libjava/javax/net/ServerSocketFactory.java
@@ -0,0 +1,122 @@
+/* ServerSocketFactory.java -- factory for server sockets.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.ServerSocket;
+
+import java.security.Security;
+
+/**
+ * A factory for server sockets. The purpose of this class is to serve
+ * as the superclass of server socket factories that produce server
+ * sockets of a particular type, such as Secure Socket Layer
+ * (SSL) server sockets.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public abstract class ServerSocketFactory
+{
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Default 0-argument constructor.
+ */
+ protected ServerSocketFactory()
+ {
+ super();
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the default server socket factory. The type of factory
+ * returned may depend upon the installation.
+ *
+ * @return The default server socket factory.
+ */
+ public static synchronized ServerSocketFactory getDefault()
+ {
+ try
+ {
+ String s = Security.getProperty("gnu.defaultServerSocketFactory");
+ if (s != null)
+ {
+ Class c = Class.forName(s);
+ return (ServerSocketFactory) c.newInstance();
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ return new VanillaServerSocketFactory();
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create an unbound server socket.
+ *
+ * @return The new server socket.
+ * @throws IOException If a networking error occurs.
+ */
+ public ServerSocket createServerSocket() throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Create a server socket bound to the given port.
+ *
+ * @param port The port to bind the server socket to.
+ * @return A server socket bound to port.
+ * @throws IOException If a networking error occurs.
+ */
+ public abstract ServerSocket createServerSocket(int port) throws IOException;
+
+ public abstract ServerSocket createServerSocket(int port, int backlog) throws IOException;
+
+ public abstract ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddress) throws IOException;
+}
diff --git a/libjava/javax/net/SocketFactory.java b/libjava/javax/net/SocketFactory.java
new file mode 100644
index 00000000000..9e236d2dfe3
--- /dev/null
+++ b/libjava/javax/net/SocketFactory.java
@@ -0,0 +1,157 @@
+/* SocketFactory.java -- factory for client sockets.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import java.security.Security;
+
+/**
+ * A factory for client sockets. The purpose of this class is to serve
+ * as the superclass of server socket factories that produce client
+ * sockets of a particular type, such as Secure Socket Layer
+ * (SSL) sockets.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public abstract class SocketFactory
+{
+
+ // Constructor.
+ // -------------------------------------------------------------------
+
+ /**
+ * Default 0-arguments constructor.
+ */
+ protected SocketFactory()
+ {
+ super();
+ }
+
+ // Class methods.
+ // -------------------------------------------------------------------
+
+ /**
+ * Returns the default socket factory. The type of factory
+ * returned may depend upon the installation.
+ *
+ * @return The default socket factory.
+ */
+ public static synchronized SocketFactory getDefault()
+ {
+ try
+ {
+ String s = Security.getProperty("gnu.defaultSocketFactory");
+ if (s != null)
+ {
+ Class c = Class.forName(s);
+ return (SocketFactory) c.newInstance();
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ return new VanillaSocketFactory();
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------
+
+ /**
+ * Returns an unbound client socket.
+ *
+ * @return The new, unbound socket.
+ */
+ public Socket createSocket() throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a socket connected to a given host on a given port.
+ *
+ * @param host The hostname to connect to.
+ * @param port The port on host to connect to.
+ * @return A socket connected to host on port.
+ * @throws IOException If a network error occurs.
+ * @throws UnknownHostException If host cannot be resolved.
+ */
+ public abstract Socket createSocket(String host, int port) throws IOException, UnknownHostException;
+
+ /**
+ * Creates a socket connected to a given host on a given port,
+ * connecting locally to the interface with the given address and port.
+ *
+ * @param host The hostname to connect to.
+ * @param port The port on host to connect to.
+ * @param localHost The address of the local interface to bind to.
+ * @param localPort The local port to bind to.
+ * @return A socket connected to host on port.
+ * @throws IOException If a network error occurs.
+ * @throws UnknownHostException If host cannot be resolved.
+ */
+ public abstract Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException;
+
+ /**
+ * Creates a socket connected to a given host on a given port.
+ *
+ * @param host The host address to connect to.
+ * @param port The port on host to connect to.
+ * @return A socket connected to host on port.
+ * @throws IOException If a network error occurs.
+ */
+ public abstract Socket createSocket(InetAddress host, int port) throws IOException;
+
+ /**
+ * Creates a socket connected to a given host on a given port,
+ * connecting locally to the interface with the given address and port.
+ *
+ * @param host The host address to connect to.
+ * @param port The port on host to connect to.
+ * @param localHost The address of the local interface to bind to.
+ * @param localPort The local port to bind to.
+ * @return A socket connected to host on port.
+ * @throws IOException If a network error occurs.
+ */
+ public abstract Socket createSocket(InetAddress hast, int port, InetAddress localHost, int localPort) throws IOException;
+}
diff --git a/libjava/javax/net/VanillaServerSocketFactory.java b/libjava/javax/net/VanillaServerSocketFactory.java
new file mode 100644
index 00000000000..e52ecba9ee3
--- /dev/null
+++ b/libjava/javax/net/VanillaServerSocketFactory.java
@@ -0,0 +1,82 @@
+/* VanillaServerSocketFactory.java -- trivial socket factory.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.ServerSocket;
+
+/**
+ * A trivial server socket factory.
+ */
+class VanillaServerSocketFactory extends ServerSocketFactory
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------
+
+ VanillaServerSocketFactory()
+ {
+ super();
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------
+
+ public ServerSocket createServerSocket() throws IOException
+ {
+ return new ServerSocket();
+ }
+
+ public ServerSocket createServerSocket(int port) throws IOException
+ {
+ return new ServerSocket(port);
+ }
+
+ public ServerSocket createServerSocket(int port, int backlog) throws IOException
+ {
+ return new ServerSocket(port, backlog);
+ }
+
+ public ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddress) throws IOException
+ {
+ return new ServerSocket(port, backlog, bindAddress);
+ }
+}
diff --git a/libjava/javax/net/VanillaSocketFactory.java b/libjava/javax/net/VanillaSocketFactory.java
new file mode 100644
index 00000000000..ace84929378
--- /dev/null
+++ b/libjava/javax/net/VanillaSocketFactory.java
@@ -0,0 +1,88 @@
+/* VanillaSocketFactory.java -- trivial socket factory.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+/**
+ * A trivial client socket factory.
+ */
+class VanillaSocketFactory extends SocketFactory
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------
+
+ VanillaSocketFactory()
+ {
+ super();
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------
+
+ public Socket createSocket() throws IOException
+ {
+ return new Socket();
+ }
+
+ public Socket createSocket(String host, int port) throws IOException, UnknownHostException
+ {
+ return new Socket(host, port);
+ }
+
+ public Socket createSocket(String host, int port, InetAddress localAddr, int localPort) throws IOException, UnknownHostException
+ {
+ return new Socket(host, port, localAddr, localPort);
+ }
+
+ public Socket createSocket(InetAddress address, int port) throws IOException
+ {
+ return new Socket(address, port);
+ }
+
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException
+ {
+ return new Socket(address, port, localAddr, localPort);
+ }
+}
diff --git a/libjava/javax/net/ssl/HandshakeCompletedEvent.java b/libjava/javax/net/ssl/HandshakeCompletedEvent.java
new file mode 100644
index 00000000000..6171ebc48e7
--- /dev/null
+++ b/libjava/javax/net/ssl/HandshakeCompletedEvent.java
@@ -0,0 +1,152 @@
+/* HandshakeCompletedEvent.java -- SSL handshake completed.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.security.cert.Certificate;
+import javax.security.cert.X509Certificate;
+
+/**
+ * An event raised by a SSLSocket and passed to the {@link
+ * HandshakeCompletedListener#handshakeCompleted(HandshakeCompletedEvent)}
+ * method of all registered listeners when a SSL handshake in a SSL
+ * protocol is completed.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public class HandshakeCompletedEvent extends java.util.EventObject
+{
+
+ // Fields.
+ // -------------------------------------------------------------------
+
+ /** Serialization constant. */
+ private static final long serialVersionUID = 7914963744257769778L;
+
+ /** The session. */
+ private transient final SSLSession session;
+
+ // Constructor.
+ // -------------------------------------------------------------------
+
+ /**
+ * Creates a new handshake completed event.
+ *
+ * @param socket The socket (also the source) creating this event.
+ * @param session The associated session object.
+ * @throws NullPointerException If session is null.
+ */
+ public HandshakeCompletedEvent(SSLSocket socket, SSLSession session)
+ {
+ super(socket);
+ if (session == null)
+ throw new NullPointerException();
+ this.session = session;
+ }
+
+ // Instance methods.
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the name of the cipher that was negotiated in this
+ * connection.
+ *
+ * @return The negotiated cipher name.
+ */
+ public String getCipherSuite()
+ {
+ if (session != null)
+ return session.getCipherSuite();
+ return null;
+ }
+
+ /**
+ * Returns the local certificates being used in this connection.
+ *
+ * @return The local certificates.
+ */
+ public Certificate[] getLocalCertificates()
+ {
+ if (session != null)
+ return session.getLocalCertificates();
+ return null;
+ }
+
+ /**
+ * Returns the peer's certificates being used in this connection.
+ *
+ * @return The peer's certificates.
+ * @throws SSLPeerUnverifiedException If the peer has not been
+ * verified.
+ */
+ public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException
+ {
+ if (session != null)
+ return session.getPeerCertificates();
+ return null;
+ }
+
+ public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException
+ {
+ if (session != null)
+ return session.getPeerCertificateChain();
+ return null;
+ }
+
+ /**
+ * Returns the SSL session object associated with this connection.
+ *
+ * @return The session object.
+ */
+ public SSLSession getSession()
+ {
+ return session;
+ }
+
+ /**
+ * Returns the socket over which this connection is being
+ * negotiated. This method is equivalent to the {@link
+ * java.util.EventObject#getSource()} method.
+ *
+ * @return The socket.
+ */
+ public SSLSocket getSocket()
+ {
+ return (SSLSocket) getSource();
+ }
+}
diff --git a/libjava/javax/net/ssl/HandshakeCompletedListener.java b/libjava/javax/net/ssl/HandshakeCompletedListener.java
new file mode 100644
index 00000000000..5b79bf973d8
--- /dev/null
+++ b/libjava/javax/net/ssl/HandshakeCompletedListener.java
@@ -0,0 +1,57 @@
+/* HandshakeCompletedListener.java -- listens for handshake events.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+/**
+ * An event listener that waits to be notified of {@link
+ * HandshakeCompletedEvent} objects created when handshake phase of
+ * the SSL protocol is completed for a particular connection.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public interface HandshakeCompletedListener extends java.util.EventListener
+{
+
+ /**
+ * Called when the handshake phase of the SSL protocol completes.
+ *
+ * @param event The event describing the new connection.
+ */
+ void handshakeCompleted(HandshakeCompletedEvent event);
+}
diff --git a/libjava/javax/net/ssl/HostnameVerifier.java b/libjava/javax/net/ssl/HostnameVerifier.java
new file mode 100644
index 00000000000..a45648effb3
--- /dev/null
+++ b/libjava/javax/net/ssl/HostnameVerifier.java
@@ -0,0 +1,64 @@
+/* HostnameVerifier.java -- verifies disparate hostnames.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+/**
+ * The interface for classes that perform hostname verification for cases
+ * when the hostname used to begin the connection (such as in a URL)
+ * does not match the hostname used in the SSL handshake.
+ * Implementations of this interface should provide an implementation
+ * of the {@link #verify(java.lang.String,javax.net.ssl.SSLSession)}
+ * method that accepts or rejects hostnames as appropriate.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public interface HostnameVerifier
+{
+
+ /**
+ * Verifies a hostname given a particular SSL session. This method
+ * should return true if the hostname is an accepted
+ * alias for the hostname negotiated in the SSL handshake.
+ *
+ * @param hostname The hostname in question.
+ * @param session The current SSL session.
+ * @return true if the hostname is acceptable.
+ */
+ boolean verify(String hostname, SSLSession session);
+}
diff --git a/libjava/javax/net/ssl/HttpsURLConnection.java b/libjava/javax/net/ssl/HttpsURLConnection.java
new file mode 100644
index 00000000000..a7b86c184b4
--- /dev/null
+++ b/libjava/javax/net/ssl/HttpsURLConnection.java
@@ -0,0 +1,256 @@
+/* HttpsURLConnection.java -- an HTTPS connection.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.cert.Certificate;
+
+/**
+ * A URL connection that connects via the Secure Socket Layer
+ * (SSL) for HTTPS connections.
+ *
+ * null,
+ * in which case some default parameters (possibly derived from system
+ * properties) should be used.
+ *
+ * @param store The key store.
+ * @param passwd The private key password.
+ * @throws KeyStoreException If the key store cannot be accessed.
+ * @throws NoSuchAlgorithmException If some of the data from the key
+ * store cannot be retrieved.
+ * @throws UnrecoverableKeyException If a private key cannot be retrieved,
+ * likely from a wrong password.
+ */
+ protected abstract void engineInit(KeyStore store, char[] passwd)
+ throws KeyStoreException, NoSuchAlgorithmException,
+ UnrecoverableKeyException;
+}
diff --git a/libjava/javax/net/ssl/ManagerFactoryParameters.java b/libjava/javax/net/ssl/ManagerFactoryParameters.java
new file mode 100644
index 00000000000..6d3e008dea9
--- /dev/null
+++ b/libjava/javax/net/ssl/ManagerFactoryParameters.java
@@ -0,0 +1,50 @@
+/* ManagerFactoryParameters.java -- marker interface for manager parameters.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+/**
+ * A marker interface for classes that serve as key or trust manager
+ * parameters, used to initialize instances of {@link
+ * KeyManagerFactory} or {@link TrustManagerFactory}.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public interface ManagerFactoryParameters
+{
+}
diff --git a/libjava/javax/net/ssl/SSLContext.java b/libjava/javax/net/ssl/SSLContext.java
new file mode 100644
index 00000000000..45e01c3c7be
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLContext.java
@@ -0,0 +1,269 @@
+/* SSLContext.java -- an SSL protocol context.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.lang.reflect.InvocationTargetException;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+
+import gnu.java.security.Engine;
+
+/**
+ * A "meta-factory" for protocol-specific socket and server socket
+ * factories. This class serves as a clearinghouse for socket
+ * factories and cached session contexts for a particular protocol,
+ * such as SSLv3.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public class SSLContext
+{
+
+ // Constants and fields.
+ // ------------------------------------------------------------------
+
+ /** Service name for SSL contexts. */
+ private static final String SSL_CONTEXT = "SSLContext";
+
+ /** The underlying engine. */
+ private final SSLContextSpi ctxSpi;
+
+ /** The provider of the engine class. */
+ private final Provider provider;
+
+ /** The protocal name. */
+ private final String protocol;
+
+ // Constructor.
+ // ------------------------------------------------------------------
+
+ /**
+ * Create a new SSL context.
+ *
+ * @param ctxSpi The context engine.
+ * @param provider The provider of the implementation.
+ * @param protocol The name of the SSL protocol.
+ */
+ protected SSLContext(SSLContextSpi ctxSpi, Provider provider,
+ String protocol)
+ {
+ this.ctxSpi = ctxSpi;
+ this.provider = provider;
+ this.protocol = protocol;
+ }
+
+ // Class methods.
+ // ------------------------------------------------------------------
+
+ /**
+ * Get an instance of a context for the specified protocol from the
+ * first provider that implements it.
+ *
+ * @param protocol The name of the protocol to get a context for.
+ * @return The new context.
+ * @throws NoSuchAlgorithm If no provider implements the given
+ * protocol.
+ */
+ public static final SSLContext getInstance(String protocol)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] provs = Security.getProviders();
+ for (int i = 0; i < provs.length; i++)
+ {
+ try
+ {
+ return getInstance(protocol, provs[i]);
+ }
+ catch (NoSuchAlgorithmException ignore)
+ {
+ }
+ }
+ throw new NoSuchAlgorithmException(protocol);
+ }
+
+ /**
+ * Get an instance of a context for the specified protocol from the
+ * named provider.
+ *
+ * @param protocol The name of the protocol to get a context for.
+ * @param provider The name of the provider to get the
+ * implementation from.
+ * @return The new context.
+ * @throws NoSuchAlgorithmException If the provider does not
+ * implement the given protocol.
+ * @throws NoSuchProviderException If the named provider does not
+ * exist.
+ * @throws IllegalArgumentException If provider is null.
+ */
+ public static final SSLContext getInstance(String protocol,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (provider == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ Provider p = Security.getProvider(provider);
+ if (p == null)
+ {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(protocol, p);
+ }
+
+ /**
+ * Get an instance of a context for the specified protocol from the
+ * specified provider.
+ *
+ * @param protocol The name of the protocol to get a context for.
+ * @param provider The name of the provider to get the
+ * implementation from.
+ * @return The new context.
+ * @throws NoSuchAlgorithmException If the provider does not
+ * implement the given protocol.
+ * @throws IllegalArgumentException If provider is null.
+ */
+ public static final SSLContext getInstance(String protocol,
+ Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ try
+ {
+ return new SSLContext((SSLContextSpi)
+ Engine.getInstance(SSL_CONTEXT, protocol, provider),
+ provider, protocol);
+ }
+ catch (InvocationTargetException ite)
+ {
+ ite.printStackTrace();
+ throw new NoSuchAlgorithmException();
+ }
+ catch (ClassCastException cce)
+ {
+ cce.printStackTrace();
+ throw new NoSuchAlgorithmException();
+ }
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------
+
+ /**
+ * Returns the set of SSL contexts available for client connections.
+ *
+ * @return The set of SSL contexts available for client connections.
+ */
+ public final SSLSessionContext getClientSessionContext()
+ {
+ return ctxSpi.engineGetClientSessionContext();
+ }
+
+ /**
+ * Returns the protocol name of this context.
+ *
+ * @return The protocol name of this context.
+ */
+ public final String getProtocol()
+ {
+ return protocol;
+ }
+
+ /**
+ * Returns the provider of this implementation.
+ *
+ * @return The provider of this implementation.
+ */
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the set of SSL contexts available for server connections.
+ *
+ * @return The set of SSL contexts available for server connections.
+ */
+ public final SSLSessionContext getServerSessionContext()
+ {
+ return ctxSpi.engineGetServerSessionContext();
+ }
+
+ /**
+ * Returns the factory for server SSL sockets.
+ *
+ * @return The factory for server SSL sockets.
+ */
+ public final SSLServerSocketFactory getServerSocketFactory()
+ {
+ return ctxSpi.engineGetServerSocketFactory();
+ }
+
+ /**
+ * Returns the factory for client SSL sockets.
+ *
+ * @return The factory for client SSL sockets.
+ */
+ public final SSLSocketFactory getSocketFactory()
+ {
+ return ctxSpi.engineGetSocketFactory();
+ }
+
+ /**
+ * Initializes this context and prepares it for producing socket
+ * factories. All of the parameters are optional; default values are
+ * used if left unspecified.
+ *
+ * @param keyManagers The set of key managers to use.
+ * @param trustManagers The set of trust managers to use.
+ * @param random A source of random bits to use.
+ * @throws KeyManagementException If initialization fails.
+ */
+ public final void init(KeyManager[] keyManagers,
+ TrustManager[] trustManagers,
+ SecureRandom random)
+ throws KeyManagementException
+ {
+ ctxSpi.engineInit(keyManagers, trustManagers, random);
+ }
+}
diff --git a/libjava/javax/net/ssl/SSLContextSpi.java b/libjava/javax/net/ssl/SSLContextSpi.java
new file mode 100644
index 00000000000..ecac1cbc5af
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLContextSpi.java
@@ -0,0 +1,109 @@
+/* SSLContextSpi.java -- SPI for SSL contexts.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.security.KeyManagementException;
+import java.security.SecureRandom;
+
+/**
+ * The Service Provider Interface (SPI) for SSLContext
+ * objects.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public abstract class SSLContextSpi
+{
+
+ // Constructor.
+ // -------------------------------------------------------------------
+
+ /**
+ * Create a new SSLContextSpi.
+ */
+ public SSLContextSpi()
+ {
+ super();
+ }
+
+ // Abstract methods.
+ // -------------------------------------------------------------------
+
+ /**
+ * Returns the set of SSL sessions available for client connections.
+ *
+ * @return The set of SSL sessions available for client connections.
+ */
+ protected abstract SSLSessionContext engineGetClientSessionContext();
+
+ /**
+ * Returns the set of SSL sessions available for server connections.
+ *
+ * @return The set of SSL sessions available for server connections.
+ */
+ protected abstract SSLSessionContext engineGetServerSessionContext();
+
+ /**
+ * Returns the SSL server socket factory.
+ *
+ * @return The SSL server socket factory.
+ */
+ protected abstract SSLServerSocketFactory engineGetServerSocketFactory();
+
+ /**
+ * Returns the SSL client socket factory.
+ *
+ * @return The SSL client socket factory.
+ */
+ protected abstract SSLSocketFactory engineGetSocketFactory();
+
+ /**
+ * Initialize this context with key and trust managers, and a source
+ * of randomness. All of the parameters are optional.
+ *
+ * @param keyManagers The set of key managers.
+ * @param trustManagers The set of trust managers.
+ * @param random The source of randomness.
+ * @throws KeyManagementException If this context cannot be
+ * initialized with these parameters.
+ */
+ protected abstract void engineInit(KeyManager[] keyManagers,
+ TrustManager[] trustManagers,
+ SecureRandom random)
+ throws KeyManagementException;
+}
diff --git a/libjava/javax/net/ssl/SSLException.java b/libjava/javax/net/ssl/SSLException.java
new file mode 100644
index 00000000000..0a33b458fa5
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLException.java
@@ -0,0 +1,59 @@
+/* SSLException.java -- generic SSL exception.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.io.IOException;
+
+/**
+ * The superclass of all possible SSL exceptions. Usually, a specific
+ * exception is thrown instead of this exception.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public class SSLException extends IOException
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------
+
+ public SSLException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/net/ssl/SSLHandshakeException.java b/libjava/javax/net/ssl/SSLHandshakeException.java
new file mode 100644
index 00000000000..c0f2c5cbb8f
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLHandshakeException.java
@@ -0,0 +1,51 @@
+/* SSLHandshakeException.java -- exception in SSL handshake.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+/**
+ * An exception that signals an error in the SSL handshake phase.
+ */
+public class SSLHandshakeException extends SSLException
+{
+
+ public SSLHandshakeException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/net/ssl/SSLKeyException.java b/libjava/javax/net/ssl/SSLKeyException.java
new file mode 100644
index 00000000000..c60cac19fe6
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLKeyException.java
@@ -0,0 +1,52 @@
+/* SSLKeyException.java -- exception in using a key in SSL.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+/**
+ * An exception signaling a problem using a public or private key in
+ * an SSL communication.
+ */
+public class SSLKeyException extends SSLException
+{
+
+ public SSLKeyException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/net/ssl/SSLPeerUnverifiedException.java b/libjava/javax/net/ssl/SSLPeerUnverifiedException.java
new file mode 100644
index 00000000000..1b3acbc2497
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLPeerUnverifiedException.java
@@ -0,0 +1,51 @@
+/* SSLPeerUnverifiedException.java -- unverified peer exception.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+/**
+ * An exception thrown when the remote peer could not be verified.
+ */
+public class SSLPeerUnverifiedException extends SSLException
+{
+
+ public SSLPeerUnverifiedException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/net/ssl/SSLPermission.java b/libjava/javax/net/ssl/SSLPermission.java
new file mode 100644
index 00000000000..3771eaf9828
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLPermission.java
@@ -0,0 +1,66 @@
+/* SSLPermission.java -- SSL permission class.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.security.BasicPermission;
+
+/**
+ * A permission used for accessing SSL classes.
+ */
+public class SSLPermission extends BasicPermission
+{
+
+ // Constant.
+ // -------------------------------------------------------------------------
+
+ private static final long serialVersionUID = -3456898025505876775L;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public SSLPermission(String name)
+ {
+ super(name);
+ }
+
+ public SSLPermission(String name, String actions)
+ {
+ super(name, actions);
+ }
+}
diff --git a/libjava/javax/net/ssl/SSLProtocolException.java b/libjava/javax/net/ssl/SSLProtocolException.java
new file mode 100644
index 00000000000..16a1457ab3e
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLProtocolException.java
@@ -0,0 +1,53 @@
+/* SSLProtocolException.java -- exception in SSL protocol.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+/**
+ * An exception thrown when a fatal protocol error is encountered. This
+ * exception usually indicates some serious problem with the local or
+ * remote SSL implementation.
+ */
+public class SSLProtocolException extends SSLException
+{
+
+ public SSLProtocolException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/libjava/javax/net/ssl/SSLServerSocket.java b/libjava/javax/net/ssl/SSLServerSocket.java
new file mode 100644
index 00000000000..eab92a23fb5
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLServerSocket.java
@@ -0,0 +1,189 @@
+// THIS IS A GENERATED FILE. DO NOT EDIT. -*- buffer-read-only: t -*-
+/* SSLServerSocket.java -- a server socket for SSL connections.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.ServerSocket;
+
+/**
+ * A server socket that allows clients to connect via the SSL protocol.
+ */
+public abstract class SSLServerSocket extends ServerSocket
+{
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ protected SSLServerSocket() throws IOException
+ {
+ super();
+ //super(0);
+ //throw new UnsupportedOperationException("1.4 socket methods not enabled");
+ }
+
+ protected SSLServerSocket(int port) throws IOException
+ {
+ super(port);
+ }
+
+ protected SSLServerSocket(int port, int backlog) throws IOException
+ {
+ super(port, backlog);
+ }
+
+ protected SSLServerSocket(int port, int backlog, InetAddress bindAddress)
+ throws IOException
+ {
+ super(port, backlog, bindAddress);
+ }
+
+ // Abstract methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the list of cihper suites that are currently enabled in this
+ * server socket. Sockets accepted by this server socket will only have
+ * these suites enabled.
+ *
+ * @return The enabled cipher suites.
+ */
+ public abstract String[] getEnabledCipherSuites();
+
+ /**
+ * Sets the list enabled cipher suites.
+ *
+ * @param suites The cipher suites to enable.
+ */
+ public abstract void setEnabledCipherSuites(String[] suites);
+
+ /**
+ * Returns the list of enabled protocols, such as "SSLv3" and "TLSv1".
+ *
+ * @return The enabled protocols.
+ */
+ public abstract String[] getEnabledProtocols();
+
+ /**
+ * Sets the list of enabled protocols.
+ *
+ * @param protocols The list of protocols to enable.
+ */
+ public abstract void setEnabledProtocols(String[] protocols);
+
+ /**
+ * Returns whether or not sessions will be created, i.e., whether or not
+ * this server socket will allow SSL session resumption.
+ *
+ * @return True if sessions will be created.
+ */
+ public abstract boolean getEnableSessionCreation();
+
+ /**
+ * Sets whether or not sessions will be created.
+ *
+ * @param enabled The new enabled value.
+ */
+ public abstract void setEnableSessionCreation(boolean enabled);
+
+ /**
+ * Returns whether or not this server socket will require clients to
+ * authenticate themselves, such as through a certificate.
+ *
+ * @return True if clients must authenticate themselves.
+ */
+ public abstract boolean getNeedClientAuth();
+
+ /**
+ * Enabled or disables the requirement that clients authenticate themselves.
+ * When this is set to true, connections will be rejected if
+ * connecting clients do not provide proper authentication.
+ *
+ * @param needAuth The new need auth value.
+ */
+ public abstract void setNeedClientAuth(boolean needAuth);
+
+ /**
+ * Returns whether or not sockets accepted by this server socket will do
+ * their handshake as the client-side. The default is false.
+ *
+ * @return True if client mode will be used.
+ */
+ public abstract boolean getUseClientMode();
+
+ /**
+ * Sets whether or not sockets accepted by this server socket will be
+ * created in client mode.
+ *
+ * @param clientMode The new client mode value.
+ */
+ public abstract void setUseClientMode(boolean clientMode);
+
+ /**
+ * Returns whether or not this socket will ask for, but not require, that
+ * connecting clients authenticate themselves. Clients that do not
+ * provide authentication they will still be allowed to connect.
+ *
+ * @return True if this server socket wants client authentication.
+ */
+ public abstract boolean getWantClientAuth();
+
+ /**
+ * Sets whether or not this server socket will want client authentication.
+ *
+ * @param wantAuth The new want auth value.
+ */
+ public abstract void setWantClientAuth(boolean wantAuth);
+
+ /**
+ * Returns a list of cipher suites that this server socket supports.
+ *
+ * @return The list of supported suites.
+ */
+ public abstract String[] getSupportedCipherSuites();
+
+ /**
+ * Returns a list of SSL protocols supported by this server socket.
+ *
+ * @return The list of supported protocols.
+ */
+ public abstract String[] getSupportedProtocols();
+}
diff --git a/libjava/javax/net/ssl/SSLServerSocketFactory.java b/libjava/javax/net/ssl/SSLServerSocketFactory.java
new file mode 100644
index 00000000000..ef82d146294
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLServerSocketFactory.java
@@ -0,0 +1,172 @@
+/* SSLServerSocketFactory.java -- factory for SSL server sockets.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.security.KeyStore;
+import java.security.Security;
+import javax.net.ServerSocketFactory;
+
+/**
+ * A server socket factory for Secure Socket Layer (SSL)
+ * server sockets.
+ */
+public abstract class SSLServerSocketFactory extends ServerSocketFactory
+{
+
+ // Field.
+ // -------------------------------------------------------------------------
+
+ private static SSLContext context;
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ protected SSLServerSocketFactory()
+ {
+ super();
+ }
+
+ // Class methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns a default implementation of a SSL server socket factory.
+ *
+ * null if there
+ * is no session, or if it has expired.
+ *
+ * @param sessionId The ID of the session to get.
+ * @return The session, or null.
+ */
+ SSLSession getSession(byte[] sessionId);
+
+ /**
+ * Returns the maximum number of sessions that may be cached by this
+ * session context.
+ *
+ * @return The maximum number of sessions that may be cached.
+ */
+ int getSessionCacheSize();
+
+ /**
+ * Returns the period of time (in seconds) that a session may be cached
+ * for before becoming invalid.
+ *
+ * @return The time a session may be valid.
+ */
+ int getSessionTimeout();
+
+ /**
+ * Sets the maximum number of sessions that may be cached by this
+ * session context. A cache size of 0 means no limit.
+ *
+ * @param size The new cache size.
+ * @throws IllegalArgumentException If size is negative.
+ */
+ void setSessionCacheSize(int size);
+
+ /**
+ * Sets the period of time (in seconds) that a session may be cached
+ * for before becoming invalid. A timeout of 0 means that sessions
+ * never expire.
+ *
+ * @param seconds The new timeout.
+ * @throws IllegalArgumentException If seconds is negative.
+ */
+ void setSessionTimeout(int seconds);
+}
diff --git a/libjava/javax/net/ssl/SSLSocket.java b/libjava/javax/net/ssl/SSLSocket.java
new file mode 100644
index 00000000000..8b943b9d6f3
--- /dev/null
+++ b/libjava/javax/net/ssl/SSLSocket.java
@@ -0,0 +1,229 @@
+/* SSLSocket.java -- an SSL client socket.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.net.ssl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+/**
+ * A socket that communicates over the secure socket layer protocol.
+ */
+public abstract class SSLSocket extends Socket
+{
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ protected SSLSocket()
+ {
+ super();
+ }
+
+ protected SSLSocket(String host, int port)
+ throws IOException, UnknownHostException
+ {
+ super(host, port);
+ }
+
+ protected SSLSocket(InetAddress address, int port) throws IOException
+ {
+ super(address, port);
+ }
+
+ protected SSLSocket(String host, int port,
+ InetAddress localAddr, int localPort)
+ throws IOException, UnknownHostException
+ {
+ super(host, port, localAddr, localPort);
+ }
+
+ protected SSLSocket(InetAddress address, int port,
+ InetAddress localAddr, int localPort)
+ throws IOException
+ {
+ super(address, port, localAddr, localPort);
+ }
+
+ // Abstract methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Adds a handshake completed listener that wants to be notified when the
+ * SSL handshake completes.
+ *
+ * @param listener The listener to add.
+ */
+ public abstract void
+ addHandshakeCompletedListener(HandshakeCompletedListener listener);
+
+ /**
+ * Removes a handshake listener from this socket.
+ *
+ * @param listener The listener to remove.
+ */
+ public abstract void
+ removeHandshakeCompletedListener(HandshakeCompletedListener listener);
+
+ /**
+ * Returns the list of currently enabled cipher suites.
+ *
+ * @return The list of enabled cipher suites.
+ */
+ public abstract String[] getEnabledCipherSuites();
+
+ /**
+ * Sets the list of enabled cipher suites.
+ *
+ * @param suites The list of suites to enable.
+ */
+ public abstract void setEnabledCipherSuites(String[] suites);
+
+ /**
+ * Returns the list of enabled SSL protocols.
+ *
+ * @return The list of enabled protocols.
+ */
+ public abstract String[] getEnabledProtocols();
+
+ /**
+ * Sets the list of enabled SSL protocols.
+ *
+ * @param protocols The list of protocols to enable.
+ */
+ public abstract void setEnabledProtocols(String[] protocols);
+
+ /**
+ * Returns whether or not sessions will be created by this socket, and thus
+ * allow sessions to be continued later.
+ *
+ * @return Whether or not sessions will be created.
+ */
+ public abstract boolean getEnableSessionCreation();
+
+ /**
+ * Sets whether or not sessions will be created by this socket.
+ *
+ * @param enable The new value.
+ */
+ public abstract void setEnableSessionCreation(boolean enable);
+
+ /**
+ * Returns whether or not this socket will require connecting clients to
+ * authenticate themselves. This value only applies to sockets in server
+ * mode.
+ *
+ * @return Whether or not this socket requires client authentication.
+ */
+ public abstract boolean getNeedClientAuth();
+
+ /**
+ * Sets whether or not this socket will require connecting clients to
+ * authenticate themselves. This value only applies to sockets in server
+ * mode.
+ *
+ * @param needAuth The new need auth value.
+ */
+ public abstract void setNeedClientAuth(boolean needAuth);
+
+ /**
+ * Returns this socket's session object.
+ *
+ * @return The session.
+ */
+ public abstract SSLSession getSession();
+
+ /**
+ * Returns the list of cipher suites supported by this socket.
+ *
+ * @return The list of supported cipher suites.
+ */
+ public abstract String[] getSupportedCipherSuites();
+
+ /**
+ * Returns the list of protocols supported by this socket.
+ *
+ * @return The list of supported protocols.
+ */
+ public abstract String[] getSupportedProtocols();
+
+ /**
+ * Returns whether or not this socket will connect in client mode.
+ *
+ * @return True if this is a client socket.
+ */
+ public abstract boolean getUseClientMode();
+
+ /**
+ * Sets whether or not this socket will connect in client mode.
+ *
+ * @param clientMode The new value.
+ */
+ public abstract void setUseClientMode(boolean clientMode);
+
+ /**
+ * Returns whether or not this socket will request that connecting clients
+ * authenticate themselves. This value only applies to sockets in server
+ * mode.
+ *
+ * @return The want client auth value.
+ */
+ public abstract boolean getWantClientAuth();
+
+ /**
+ * Sets whether or not this socket will request that connecting clients
+ * authenticate themselves. This value only applies to sockets in server
+ * mode.
+ *
+ * @param wantAuth The new want auth value.
+ */
+ public abstract void setWantClientAuth(boolean wantAuth);
+
+ /**
+ * Explicitly begins the handshake, or, if the handshake has already
+ * completed, requests that the handshake be repeated.
+ *
+ *
+ *
+ */
+public final class AuthPermission extends BasicPermission
+{
+
+ /**
+ * Creates a new authentication permission for the given target name.
+ *
+ * @param name The target name.
+ */
+ public AuthPermission (String name)
+ {
+ super (name);
+ }
+
+ /**
+ * Creates a new authentication permission for the given target name.
+ * The actions list is not used by this class.
+ *
+ * @param name The target name.
+ * @param actions The action list.
+ */
+ public AuthPermission (String name, String actions)
+ {
+ super (name, actions);
+ }
+}
diff --git a/libjava/javax/security/auth/DestroyFailedException.java b/libjava/javax/security/auth/DestroyFailedException.java
new file mode 100644
index 00000000000..00bbd89667f
--- /dev/null
+++ b/libjava/javax/security/auth/DestroyFailedException.java
@@ -0,0 +1,67 @@
+/* DestroyFailedException.java -- signals an object could not be destroyed.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth;
+
+/**
+ * An exception thrown when the {@link Destroyable#destroy()} method
+ * fails for a credential.
+ *
+ * @see Destroyable
+ */
+public class DestroyFailedException extends Exception
+{
+
+ /**
+ * Creates a new DestroyFailedException with no detail message.
+ */
+ public DestroyFailedException()
+ {
+ super();
+ }
+
+ /**
+ * Creates a new DestroyFailedException with a detail message.
+ *
+ * @param message The detail message.
+ */
+ public DestroyFailedException (String message)
+ {
+ super (message);
+ }
+}
diff --git a/libjava/javax/security/auth/Destroyable.java b/libjava/javax/security/auth/Destroyable.java
new file mode 100644
index 00000000000..484bece8de9
--- /dev/null
+++ b/libjava/javax/security/auth/Destroyable.java
@@ -0,0 +1,64 @@
+/* Destroyable.java -- an immutable object that may be destroyed.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth;
+
+/**
+ * An interface for objects that are immutable but whose sensitive
+ * data may be wiped out.
+ */
+public interface Destroyable
+{
+
+ /**
+ * Destroy this object, clearing all sensitive fields appropriately.
+ *
+ * @throws DestroyFailedException If this object could not be
+ * destroyed.
+ * @throws SecurityException If the caller does not have permission
+ * to destroy this object.
+ */
+ void destroy() throws DestroyFailedException;
+
+ /**
+ * Tells whether or not this object has been destroyed.
+ *
+ * @return True if this object has been destroyed.
+ */
+ boolean isDestroyed();
+}
diff --git a/libjava/javax/security/auth/Policy.java b/libjava/javax/security/auth/Policy.java
new file mode 100644
index 00000000000..2234d85732b
--- /dev/null
+++ b/libjava/javax/security/auth/Policy.java
@@ -0,0 +1,79 @@
+/* Policy.java -- deprecated precursor to java.security.Policy.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth;
+
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+
+/**
+ * @deprecated The classes java.security.Policy and
+ * java.security.ProtectionDomain provide the functionality of this class.
+ */
+public abstract class Policy
+{
+
+ private static Policy policy;
+
+ protected Policy()
+ {
+ }
+
+ public static synchronized Policy getPolicy()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("getPolicy"));
+ }
+ return policy;
+ }
+
+ public static synchronized void setPolicy (Policy p)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("setPolicy"));
+ }
+ policy = p;
+ }
+
+ public abstract PermissionCollection getPermissions (Subject subject, CodeSource source);
+ public abstract void refresh();
+}
diff --git a/libjava/javax/security/auth/PrivateCredentialPermission.java b/libjava/javax/security/auth/PrivateCredentialPermission.java
new file mode 100644
index 00000000000..db9fed7939d
--- /dev/null
+++ b/libjava/javax/security/auth/PrivateCredentialPermission.java
@@ -0,0 +1,322 @@
+/* PrivateCredentialPermission.java -- permissions governing private credentials.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth;
+
+import java.io.Serializable;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * A permission governing access to a private credential. The action of this
+ * permission is always "read" -- meaning that the private credential
+ * information can be read from an object.
+ *
+ * doAsdoAsPrivilegedgetSubjectgetSubjectFromDomainCombinersetReadOnlymodifyPrincipalsmodifyPublicCredentialsmodifyPrivateCredentialsrefreshCredentialdestroyCredentialcreateLoginContext.name'*'),
+ * which allows the creation of a context with any name.getLoginConfigurationsetLoginConfigurationrefreshLoginConfigurationCredentialClassName ( PrinicpalClassName PrincipalName )*'*').
+ * PrinicpalClassName is the class name of a principal object, and
+ * PrincipalName is a string representing the principal, or the
+ * wildcard character."read".
+ */
+ public PrivateCredentialPermission (final String name, String actions)
+ {
+ super(name);
+ actions = actions.trim().toLowerCase();
+ if (!"read".equals (actions))
+ {
+ throw new IllegalArgumentException("actions must be \"read\"");
+ }
+ StringTokenizer st = new StringTokenizer (name, " \"'");
+ principals = new HashSet();
+ if (st.countTokens() < 3 || (st.countTokens() & 1) == 0)
+ {
+ throw new IllegalArgumentException ("badly formed credential name");
+ }
+ credentialClass = st.nextToken();
+ while (st.hasMoreTokens())
+ {
+ principals.add (new CredOwner (st.nextToken(), st.nextToken()));
+ }
+ testing = false; // WTF ever.
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public boolean equals (Object o)
+ {
+ if (! (o instanceof PrivateCredentialPermission))
+ {
+ return false;
+ }
+ PrivateCredentialPermission that = (PrivateCredentialPermission) o;
+ if (!that.getActions().equals (getActions()))
+ {
+ return false;
+ }
+ if (!that.getCredentialClass().equals (getCredentialClass()))
+ {
+ return false;
+ }
+
+ final String[][] principals = getPrincipals();
+ final String[][] that_principals = that.getPrincipals();
+ if (that_principals == null)
+ {
+ return false;
+ }
+ if (that_principals.length != principals.length)
+ {
+ return false;
+ }
+ for (int i = 0; i < principals.length; i++)
+ {
+ if (!principals[i][0].equals (that_principals[i][0]) ||
+ !principals[i][1].equals (that_principals[i][1]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the actions this permission encompasses. For private credential
+ * permissions, this is always the string "read".
+ *
+ * @return The list of actions.
+ */
+ public String getActions()
+ {
+ return "read";
+ }
+
+ /**
+ * Returns the credential class name that was embedded in this permission's
+ * target name.
+ *
+ * @return The credential class name.
+ */
+ public String getCredentialClass()
+ {
+ return credentialClass;
+ }
+
+ /**
+ * Returns the principal list that was embedded in this permission's target
+ * name.
+ *
+ *
+ *
+ *
+ * @param p The permission to check.
+ * @return True if this permission implies p.
+ */
+ public boolean implies (Permission p)
+ {
+ if (! (p instanceof PrivateCredentialPermission))
+ {
+ return false;
+ }
+ PrivateCredentialPermission that = (PrivateCredentialPermission) p;
+ if (!credentialClass.equals ("*")
+ && !credentialClass.equals (that.getCredentialClass()))
+ {
+ return false;
+ }
+ String[][] principals = getPrincipals();
+ String[][] that_principals = that.getPrincipals();
+ if (that_principals == null)
+ {
+ return false;
+ }
+ for (int i = 0; i < principals.length; i++)
+ {
+ for (int j = 0; j < that_principals.length; j++)
+ {
+ if (principals[i][0].equals (that_principals[j][0]) &&
+ (principals[i][1].equals ("*") ||
+ principals[i][1].equals (that_principals[j][1])))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * This method is not necessary for this class, thus it always returns null.
+ *
+ * @return null.
+ */
+ public PermissionCollection newPermissionCollection()
+ {
+ return null;
+ }
+
+ // Inner class.
+ // -------------------------------------------------------------------------
+
+ /**
+ * An undocumented inner class present for serialization compatibility.
+ */
+ private static class CredOwner implements Serializable
+ {
+
+ // Fields.
+ // -----------------------------------------------------------------------
+
+ private final String principalClass;
+ private final String principalName;
+
+ // Constructor.
+ // -----------------------------------------------------------------------
+
+ CredOwner (final String principalClass, final String principalName)
+ {
+ this.principalClass = principalClass;
+ this.principalName = principalName;
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------------
+
+ public boolean equals (Object o)
+ {
+ if (!(o instanceof CredOwner))
+ {
+ return false;
+ }
+ return principalClass.equals (((CredOwner) o).getPrincipalClass()) &&
+ principalName.equals (((CredOwner) o).getPrincipalName());
+ }
+
+ public int hashCode()
+ {
+ return principalClass.hashCode() + principalName.hashCode();
+ }
+
+ public String getPrincipalClass()
+ {
+ return principalClass;
+ }
+
+ public String getPrincipalName()
+ {
+ return principalName;
+ }
+ }
+}
diff --git a/libjava/javax/security/auth/RefreshFailedException.java b/libjava/javax/security/auth/RefreshFailedException.java
new file mode 100644
index 00000000000..5be9ab75ed6
--- /dev/null
+++ b/libjava/javax/security/auth/RefreshFailedException.java
@@ -0,0 +1,63 @@
+/* RefreshFailedException.java -- signals a failed refresh.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth;
+
+/**
+ * A signal that a call to {@link Refreshable#refresh()} failed.
+ */
+public class RefreshFailedException extends Exception
+{
+
+ /**
+ * Create a new RefreshFailedException with no detail message.
+ */
+ public RefreshFailedException()
+ {
+ }
+
+ /**
+ * Create a new RefreshFailedException with a detail message.
+ *
+ * @param message The detail message.
+ */
+ public RefreshFailedException (String message)
+ {
+ super (message);
+ }
+}
diff --git a/libjava/javax/security/auth/Refreshable.java b/libjava/javax/security/auth/Refreshable.java
new file mode 100644
index 00000000000..b3ceded417a
--- /dev/null
+++ b/libjava/javax/security/auth/Refreshable.java
@@ -0,0 +1,65 @@
+/* Refreshable.java -- an object whose state may be refreshed.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth;
+
+/**
+ * An object whose internal state may be refreshed: as in a
+ * credential object with a expiry date.
+ */
+public interface Refreshable
+{
+
+ /**
+ * Tells whether or not this object is current. Refreshable objects that
+ * are not current may need to be refreshed.
+ *
+ * @return Whether this object is current.
+ */
+ boolean isCurrent();
+
+ /**
+ * Refresh this object. The process involved in refreshing an object is
+ * per-implementation dependent.
+ *
+ * @throws RefreshFailedException If refreshing this object fails.
+ * @throws SecurityException If the caller does not have permission to
+ * refresh, or to take the steps involved in refreshing, this object.
+ */
+ void refresh() throws RefreshFailedException;
+}
diff --git a/libjava/javax/security/auth/Subject.java b/libjava/javax/security/auth/Subject.java
new file mode 100644
index 00000000000..264a41c0561
--- /dev/null
+++ b/libjava/javax/security/auth/Subject.java
@@ -0,0 +1,559 @@
+/* Subject.java -- a single entity in the system.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.DomainCombiner;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+
+/**
+ *
+ */
+public final class Subject implements Serializable
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private static final long serialVersionUID = -8308522755600156056L;
+
+ /**
+ * @serial The set of principals. The type of this field is SecureSet, a
+ * private inner class.
+ */
+ private final Set principals;
+
+ /**
+ * @serial The read-only flag.
+ */
+ private boolean readOnly;
+
+ private transient final SecureSet pubCred;
+ private transient final SecureSet privCred;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public Subject()
+ {
+ principals = new SecureSet (this, SecureSet.PRINCIPALS);
+ pubCred = new SecureSet (this, SecureSet.PUBLIC_CREDENTIALS);
+ privCred = new SecureSet (this, SecureSet.PRIVATE_CREDENTIALS);
+ readOnly = false;
+ }
+
+ public Subject (final boolean readOnly, final Set principals,
+ final Set pubCred, final Set privCred)
+ {
+ if (principals == null || pubCred == null || privCred == null)
+ {
+ throw new NullPointerException();
+ }
+ this.principals = new SecureSet (this, SecureSet.PRINCIPALS, principals);
+ this.pubCred = new SecureSet (this, SecureSet.PUBLIC_CREDENTIALS, pubCred);
+ this.privCred = new SecureSet (this, SecureSet.PRIVATE_CREDENTIALS, privCred);
+ this.readOnly = readOnly;
+ }
+
+ // Class methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ *
+ *
+ * [ * P "foo" ] implies [ C P "foo" ][ C P1 "foo" ] implies [ C P1 "foo" P2 "bar" ][ C P1 "*" ] implies [ C P1 "foo" ]null
+ * if there is none.
+ * @throws NullPointerException If subject is null.
+ * @throws SecurityException If the caller does not have permission to get
+ * the subject ("getSubject" target of {@link AuthPermission}.
+ */
+ public static Subject getSubject (final AccessControlContext context)
+ {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("getSubject"));
+ }
+ DomainCombiner dc = context.getDomainCombiner();
+ if (!(dc instanceof SubjectDomainCombiner))
+ {
+ return null;
+ }
+ return ((SubjectDomainCombiner) dc).getSubject();
+ }
+
+ /**
+ * "doAs" target of {@link AuthPermission}.
+ */
+ public static Object doAs (final Subject subject, final PrivilegedAction action)
+ {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("doAs"));
+ }
+ AccessControlContext context =
+ new AccessControlContext (AccessController.getContext(),
+ new SubjectDomainCombiner (subject));
+ return AccessController.doPrivileged (action, context);
+ }
+
+ /**
+ * "doAs" target of {@link AuthPermission}.
+ * @throws PrivilegedActionException If the action throws an exception.
+ */
+ public static Object doAs (final Subject subject,
+ final PrivilegedExceptionAction action)
+ throws PrivilegedActionException
+ {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("doAs"));
+ }
+ AccessControlContext context =
+ new AccessControlContext (AccessController.getContext(),
+ new SubjectDomainCombiner(subject));
+ return AccessController.doPrivileged (action, context);
+ }
+
+ /**
+ * "doAsPrivileged" target of {@link
+ * AuthPermission}.
+ */
+ public static Object doAsPrivileged (final Subject subject,
+ final PrivilegedAction action,
+ final AccessControlContext acc)
+ {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("doAsPrivileged"));
+ }
+ AccessControlContext context =
+ new AccessControlContext (acc, new SubjectDomainCombiner (subject));
+ return AccessController.doPrivileged (action, context);
+ }
+
+ /**
+ * "doAsPrivileged" target of
+ * {@link AuthPermission}.
+ * @throws PrivilegedActionException If the action throws an exception.
+ */
+ public static Object doAsPrivileged (final Subject subject,
+ final PrivilegedExceptionAction action,
+ final AccessControlContext acc)
+ throws PrivilegedActionException
+ {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("doAsPrivileged"));
+ }
+ AccessControlContext context =
+ new AccessControlContext (acc, new SubjectDomainCombiner (subject));
+ return AccessController.doPrivileged (action, context);
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public boolean equals (Object o)
+ {
+ if (!(o instanceof Subject))
+ {
+ return false;
+ }
+ Subject that = (Subject) o;
+ return principals.containsAll (that.getPrincipals()) &&
+ pubCred.containsAll (that.getPublicCredentials()) &&
+ privCred.containsAll (that.getPrivateCredentials());
+ }
+
+ public Set getPrincipals()
+ {
+ return principals;
+ }
+
+ public Set getPrincipals(Class clazz)
+ {
+ HashSet result = new HashSet (principals.size());
+ for (Iterator it = principals.iterator(); it.hasNext(); )
+ {
+ Object o = it.next();
+ if (o != null && clazz.isAssignableFrom (o.getClass()))
+ {
+ result.add(o);
+ }
+ }
+ return Collections.unmodifiableSet (result);
+ }
+
+ public Set getPrivateCredentials()
+ {
+ return privCred;
+ }
+
+ public Set getPrivateCredentials (Class clazz)
+ {
+ HashSet result = new HashSet (privCred.size());
+ for (Iterator it = privCred.iterator(); it.hasNext(); )
+ {
+ Object o = it.next();
+ if (o != null && clazz.isAssignableFrom (o.getClass()))
+ {
+ result.add(o);
+ }
+ }
+ return Collections.unmodifiableSet (result);
+ }
+
+ public Set getPublicCredentials()
+ {
+ return pubCred;
+ }
+
+ public Set getPublicCredentials (Class clazz)
+ {
+ HashSet result = new HashSet (pubCred.size());
+ for (Iterator it = pubCred.iterator(); it.hasNext(); )
+ {
+ Object o = it.next();
+ if (o != null && clazz.isAssignableFrom (o.getClass()))
+ {
+ result.add(o);
+ }
+ }
+ return Collections.unmodifiableSet (result);
+ }
+
+ public int hashCode()
+ {
+ return principals.hashCode() + privCred.hashCode() + pubCred.hashCode();
+ }
+
+ /**
+ * "setReadOnly" target of
+ * {@link AuthPermission}.
+ */
+ public void setReadOnly()
+ {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("setReadOnly"));
+ }
+ readOnly = true;
+ }
+
+ public String toString()
+ {
+ return Subject.class.getName() + " [ principals=" + principals +
+ ", private credentials=" + privCred + ", public credentials=" +
+ pubCred + ", read-only=" + readOnly + " ]";
+ }
+
+// Inner class.
+ // -------------------------------------------------------------------------
+
+ /**
+ * An undocumented inner class that is used for sets in the parent class.
+ */
+ private static class SecureSet extends AbstractSet implements Serializable
+ {
+
+ // Fields.
+ // -----------------------------------------------------------------------
+
+ private static final long serialVersionUID = 7911754171111800359L;
+
+ static final int PRINCIPALS = 0;
+ static final int PUBLIC_CREDENTIALS = 1;
+ static final int PRIVATE_CREDENTIALS = 2;
+
+ private final Subject subject;
+ private final LinkedList elements;
+ private transient final int type;
+
+ // Constructors.
+ // -----------------------------------------------------------------------
+
+ SecureSet (final Subject subject, final int type, final Collection elements)
+ {
+ this (subject, type);
+ for (Iterator it = elements.iterator(); it.hasNext(); )
+ {
+ Object o = it.next();
+ if (type == PRINCIPALS && !(o instanceof Principal))
+ {
+ throw new IllegalArgumentException(o+" is not a Principal");
+ }
+ if (!elements.contains (o))
+ {
+ elements.add (o);
+ }
+ }
+ }
+
+ SecureSet (final Subject subject, final int type)
+ {
+ this.subject = subject;
+ this.type = type;
+ this.elements = new LinkedList();
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------------
+
+ public synchronized int size()
+ {
+ return elements.size();
+ }
+
+ public Iterator iterator()
+ {
+ return elements.iterator();
+ }
+
+ public synchronized boolean add(Object element)
+ {
+ if (subject.isReadOnly())
+ {
+ throw new IllegalStateException ("subject is read-only");
+ }
+ final SecurityManager sm = System.getSecurityManager();
+ switch (type)
+ {
+ case PRINCIPALS:
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("modifyPrincipals"));
+ }
+ if (!(element instanceof Principal))
+ {
+ throw new IllegalArgumentException ("element is not a Principal");
+ }
+ break;
+
+ case PUBLIC_CREDENTIALS:
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("modifyPublicCredentials"));
+ }
+ break;
+
+ case PRIVATE_CREDENTIALS:
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("modifyPrivateCredentials"));
+ }
+ break;
+
+ default:
+ throw new Error ("this statement should be unreachable");
+ }
+
+ if (elements.contains (element))
+ {
+ return false;
+ }
+
+ return elements.add (element);
+ }
+
+ public synchronized boolean remove (final Object element)
+ {
+ if (subject.isReadOnly())
+ {
+ throw new IllegalStateException ("subject is read-only");
+ }
+ final SecurityManager sm = System.getSecurityManager();
+ switch (type)
+ {
+ case PRINCIPALS:
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("modifyPrincipals"));
+ }
+ if (!(element instanceof Principal))
+ {
+ throw new IllegalArgumentException ("element is not a Principal");
+ }
+ break;
+
+ case PUBLIC_CREDENTIALS:
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("modifyPublicCredentials"));
+ }
+ break;
+
+ case PRIVATE_CREDENTIALS:
+ if (sm != null)
+ {
+ sm.checkPermission (new AuthPermission ("modifyPrivateCredentials"));
+ }
+ break;
+
+ default:
+ throw new Error("this statement should be unreachable");
+ }
+
+ return elements.remove(element);
+ }
+
+ public synchronized boolean contains (final Object element)
+ {
+ return elements.remove (element);
+ }
+
+ public boolean removeAll (final Collection c)
+ {
+ if (subject.isReadOnly())
+ {
+ throw new IllegalStateException ("subject is read-only");
+ }
+ return super.removeAll (c);
+ }
+
+ public boolean retainAll (final Collection c)
+ {
+ if (subject.isReadOnly())
+ {
+ throw new IllegalStateException ("subject is read-only");
+ }
+ return super.retainAll (c);
+ }
+
+ public void clear()
+ {
+ if (subject.isReadOnly())
+ {
+ throw new IllegalStateException ("subject is read-only");
+ }
+ elements.clear();
+ }
+
+ private synchronized void writeObject (ObjectOutputStream out)
+ throws IOException
+ {
+ throw new UnsupportedOperationException ("FIXME: determine serialization");
+ }
+
+ private void readObject (ObjectInputStream in)
+ throws ClassNotFoundException, IOException
+ {
+ throw new UnsupportedOperationException ("FIXME: determine serialization");
+ }
+ }
+}
diff --git a/libjava/javax/security/auth/SubjectDomainCombiner.java b/libjava/javax/security/auth/SubjectDomainCombiner.java
new file mode 100644
index 00000000000..194e1130a2a
--- /dev/null
+++ b/libjava/javax/security/auth/SubjectDomainCombiner.java
@@ -0,0 +1,96 @@
+/* SubjectDomainCombiner.java -- domain combiner for Subjects.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth;
+
+import java.security.DomainCombiner;
+import java.security.Principal;
+import java.security.ProtectionDomain;
+
+import java.util.LinkedList;
+
+public class SubjectDomainCombiner implements DomainCombiner
+{
+
+ // Field.
+ // -------------------------------------------------------------------------
+
+ private final Subject subject;
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ public SubjectDomainCombiner (final Subject subject)
+ {
+ this.subject = subject;
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public ProtectionDomain[] combine (final ProtectionDomain[] current,
+ final ProtectionDomain[] assigned)
+ {
+ LinkedList domains = new LinkedList();
+ Principal[] principals =
+ (Principal[]) subject.getPrincipals().toArray (new Principal[0]);
+ if (current != null)
+ {
+ for (int i = 0; i < current.length; i++)
+ {
+ domains.add (new ProtectionDomain (current[i].getCodeSource(),
+ current[i].getPermissions(),
+ current[i].getClassLoader(),
+ principals));
+ }
+ }
+ if (assigned != null)
+ {
+ for (int i = 0; i < assigned.length; i++)
+ {
+ domains.add (assigned[i]);
+ }
+ }
+ return (ProtectionDomain[]) domains.toArray (new ProtectionDomain[domains.size()]);
+ }
+
+ public Subject getSubject()
+ {
+ return subject;
+ }
+}
diff --git a/libjava/javax/security/auth/callback/Callback.java b/libjava/javax/security/auth/callback/Callback.java
new file mode 100644
index 00000000000..655ad3348ba
--- /dev/null
+++ b/libjava/javax/security/auth/callback/Callback.java
@@ -0,0 +1,65 @@
+/* Callback.java -- marker interface for callback classes
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.callback;
+
+/**
+ * Callback implementations do not retrieve or display the
+ * information requested by underlying security services. Callback
+ * implementations simply provide the means to pass such requests to
+ * applications, and for applications, if appropriate, to return requested
+ * information back to the underlying security services.CallbackHandler and passes it to
+ * underlying security services so that they may interact with the application
+ * to retrieve specific authentication data, such as usernames and passwords, or
+ * to display certain information, such as error and warning messages.CallbackHandlers are implemented in an application-dependent
+ * fashion. For example, implementations for an application with a graphical
+ * user interface (GUI) may pop up windows to prompt for requested information
+ * or to display error messages. An implementation may also choose to obtain
+ * requested information from an alternate source without asking the end user.CallbackHandler.
+ * The CallbackHandler implementation decides how to retrieve and
+ * display information depending on the {@link Callback}s passed to it. For
+ * example, if the underlying service needs a username and password to
+ * authenticate a user, it uses a {@link NameCallback} and
+ * {@link PasswordCallback}. The CallbackHandler can then choose
+ * to prompt for a username and password serially, or to prompt for both in a
+ * single window.CallbackHandler class implementation may be
+ * specified in the auth.login.defaultCallbackHandler security
+ * property. The security property can be set in the Java security properties
+ * file located in the file named
+ * <JAVA_HOME>/lib/security/java.security, where
+ * <JAVA_HOME> refers to the directory where the SDK was
+ * installed.CallbackHandler implementation class, then a
+ * LoginContextwill load the specified CallbackHandler
+ * and pass it to the underlying LoginModules. The
+ * LoginContext only loads the default handler if one was not
+ * provided.handle() method implementation checks the instance(s)
+ * of the {@link Callback} object(s) passed in to retrieve or display the
+ * requested information. The following example is provided to help
+ * demonstrate what an handle() method implementation might look
+ * like. This example code is for guidance only. Many details, including
+ * proper error handling, are left out for simplicity.
+ *public void handle(Callback[] callbacks)
+ *throws IOException, UnsupportedCallbackException {
+ * for (int i = 0; i < callbacks.length; i++) {
+ * if (callbacks[i] instanceof TextOutputCallback) {
+ * // display the message according to the specified type
+ * TextOutputCallback toc = (TextOutputCallback)callbacks[i];
+ * switch (toc.getMessageType()) {
+ * case TextOutputCallback.INFORMATION:
+ * System.out.println(toc.getMessage());
+ * break;
+ * case TextOutputCallback.ERROR:
+ * System.out.println("ERROR: " + toc.getMessage());
+ * break;
+ * case TextOutputCallback.WARNING:
+ * System.out.println("WARNING: " + toc.getMessage());
+ * break;
+ * default:
+ * throw new IOException("Unsupported message type: "
+ * + toc.getMessageType());
+ * }
+ * } else if (callbacks[i] instanceof NameCallback) {
+ * // prompt the user for a username
+ * NameCallback nc = (NameCallback)callbacks[i];
+ * // ignore the provided defaultName
+ * System.err.print(nc.getPrompt());
+ * System.err.flush();
+ * nc.setName((new BufferedReader(
+ * new InputStreamReader(System.in))).readLine());
+ * } else if (callbacks[i] instanceof PasswordCallback) {
+ * // prompt the user for sensitive information
+ * PasswordCallback pc = (PasswordCallback)callbacks[i];
+ * System.err.print(pc.getPrompt());
+ * System.err.flush();
+ * pc.setPassword(readPassword(System.in));
+ * } else {
+ * throw new UnsupportedCallbackException(
+ * callbacks[i], "Unrecognized Callback");
+ * }
+ * }
+ *}
+ *
+ * // Reads user password from given input stream.
+ *private char[] readPassword(InputStream in) throws IOException {
+ * // insert code to read a user password from the input stream
+ *}
+ *
+ *
+ * @param callbacks an array of {@link Callback} objects provided by an
+ * underlying security service which contains the information requested to
+ * be retrieved or displayed.
+ * @throws IOException if an input or output error occurs.
+ * @throws UnsupportedCallbackException if the implementation of this method
+ * does not support one or more of the Callbacks specified in the
+ * callbacks parameter.
+ */
+ void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException;
+}
diff --git a/libjava/javax/security/auth/callback/ChoiceCallback.java b/libjava/javax/security/auth/callback/ChoiceCallback.java
new file mode 100644
index 00000000000..44b5ffcba5e
--- /dev/null
+++ b/libjava/javax/security/auth/callback/ChoiceCallback.java
@@ -0,0 +1,237 @@
+/* ChoiceCallback.java -- callback for a choice of values.
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a
+ * ChoiceCallback to the handle() method of a
+ * {@link CallbackHandler} to display a list of choices and to retrieve the
+ * selected choice(s).
+ *
+ * @see CallbackHandler
+ * @version $Revision: 1.1 $
+ */
+public class ChoiceCallback implements Callback, Serializable
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private String prompt;
+
+ /**
+ * @serial the list of choices.
+ * @since 1.4
+ */
+ private String[] choices;
+
+ /**
+ * @serial the choice to be used as the default choice.
+ * @since 1.4
+ */
+ private int defaultChoice;
+
+ /**
+ * @serial whether multiple selections are allowed from the list of choices.
+ * @since 1.4
+ */
+ private boolean multipleSelectionsAllowed;
+
+ /**
+ * @serial the selected choices, represented as indexes into the choices list.
+ * @since 1.4
+ */
+ private int[] selections;
+
+ // Constructor(s)
+ //--------------------------------------------------------------------------
+
+ /**
+ * Construct a ChoiceCallback with a prompt, a list of choices,
+ * a default choice, and a boolean specifying whether or not multiple
+ * selections from the list of choices are allowed.
+ *
+ * @param prompt the prompt used to describe the list of choices.
+ * @param choices the list of choices.
+ * @param defaultChoice the choice to be used as the default choice when the
+ * list of choices are displayed. This value is represented as an index into
+ * the choices array.
+ * @param multipleSelectionsAllowed boolean specifying whether or not
+ * multiple selections can be made from the list of choices.
+ * @throws IllegalArgumentException if prompt is null,
+ * if prompt has a length of 0, if choices
+ * is null, if choices has a length of 0,
+ * if any element from choices is null, if any
+ * element from choices has a length of 0 or if
+ * defaultChoice does not fall within the array boundaries of
+ * choices.
+ */
+ public ChoiceCallback(String prompt, String[] choices, int defaultChoice,
+ boolean multipleSelectionsAllowed)
+ {
+ super();
+
+ setPrompt(prompt);
+ setChoices(choices);
+ if (defaultChoice < 0 || defaultChoice >= this.choices.length)
+ {
+ throw new IllegalArgumentException("default choice is out of bounds");
+ }
+ this.defaultChoice = defaultChoice;
+ this.multipleSelectionsAllowed = multipleSelectionsAllowed;
+ }
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Get the prompt.
+ *
+ * @return the prompt.
+ */
+ public String getPrompt()
+ {
+ return prompt;
+ }
+
+ /**
+ * Get the list of choices.
+ *
+ * @return the list of choices.
+ */
+ public String[] getChoices()
+ {
+ return choices;
+ }
+
+ /**
+ * Get the defaultChoice.
+ *
+ * @return the defaultChoice, represented as an index into the choices list.
+ */
+ public int getDefaultChoice()
+ {
+ return defaultChoice;
+ }
+
+ /**
+ * Get the boolean determining whether multiple selections from the choices
+ * list are allowed.
+ *
+ * @return whether multiple selections are allowed.
+ */
+ public boolean allowMultipleSelections()
+ {
+ return multipleSelectionsAllowed;
+ }
+
+ /**
+ * Set the selected choice.
+ *
+ * @param selection the selection represented as an index into the choices
+ * list.
+ * @see #getSelectedIndexes()
+ */
+ public void setSelectedIndex(int selection)
+ {
+ this.selections = new int[1];
+ this.selections[0] = selection;
+ }
+
+ /**
+ * Set the selected choices.
+ *
+ * @param selections the selections represented as indexes into the choices
+ * list.
+ * @throws UnsupportedOperationException if multiple selections are not
+ * allowed, as determined by allowMultipleSelections.
+ * @see #getSelectedIndexes()
+ */
+ public void setSelectedIndexes(int[] selections)
+ {
+ if (!multipleSelectionsAllowed)
+ {
+ throw new UnsupportedOperationException("not allowed");
+ }
+
+ this.selections = selections;
+ }
+
+ /**
+ * Get the selected choices.
+ *
+ * @return the selected choices, represented as indexes into the choices list.
+ * @see #setSelectedIndexes(int[])
+ */
+ public int[] getSelectedIndexes()
+ {
+ return selections;
+ }
+
+ private void setPrompt(String prompt) throws IllegalArgumentException
+ {
+ if ((prompt == null) || (prompt.length() == 0))
+ {
+ throw new IllegalArgumentException("invalid prompt");
+ }
+ this.prompt = prompt;
+ }
+
+ private void setChoices(String[] choices) throws IllegalArgumentException
+ {
+ if (choices == null || choices.length == 0)
+ {
+ throw new IllegalArgumentException("invalid choices");
+ }
+ for (int i = 0; i < choices.length; i++)
+ {
+ if (choices[i] == null || choices[i].length() == 0)
+ {
+ throw new IllegalArgumentException("invalid choice at index #"+i);
+ }
+ }
+ this.choices = choices;
+ }
+}
diff --git a/libjava/javax/security/auth/callback/ConfirmationCallback.java b/libjava/javax/security/auth/callback/ConfirmationCallback.java
new file mode 100644
index 00000000000..8abd393f52c
--- /dev/null
+++ b/libjava/javax/security/auth/callback/ConfirmationCallback.java
@@ -0,0 +1,506 @@
+/* ConfirmationCallback.java -- callback for confirmations.
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a
+ * ConfirmationCallback to the handle() method of a
+ * {@link CallbackHandler} to ask for YES/NO, OK/CANCEL, YES/NO/CANCEL or other
+ * similar confirmations.
+ *
+ * @see CallbackHandler
+ * @version $Revision: 1.1 $
+ */
+public class ConfirmationCallback implements Callback, Serializable
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /**
+ * getOptionType method returns this value if this
+ * ConfirmationCallback was instantiated with options
+ * instead of an optionType.optionType
+ * to a ConfirmationCallback constructor if it requires a
+ * confirmation which can be answered with either YES or
+ * NO.optionType
+ * to a ConfirmationCallback constructor if it requires a
+ * confirmation which can be answered with either YES,
+ * NO or CANCEL.
+ */
+ public static final int YES_NO_CANCEL_OPTION = 1;
+
+ /**
+ * optionType
+ * to a ConfirmationCallback constructor if it requires a
+ * confirmation which can be answered with either OK or
+ * CANCEL.optionType was specified to this
+ * ConfirmationCallback, this option may be specified as a
+ * defaultOption or returned as the selected index.optionType was specified to this
+ * ConfirmationCallback, this option may be specified as a
+ * defaultOption or returned as the selected index.optionType was specified to this
+ * ConfirmationCallback, this option may be specified as a
+ * defaultOption or returned as the selected index.optionType was specified to this
+ * ConfirmationCallback, this option may be specified as a
+ * defaultOption or returned as the selected index.ConfirmationCallback with a message type, an
+ * option type and a default option.messageType is not either
+ * INFORMATION, WARNING, or ERROR, if
+ * optionType is not either YES_NO_OPTION,
+ * YES_NO_CANCEL_OPTION, or OK_CANCEL_OPTION, or if
+ * defaultOption does not correspond to one of the options in
+ * optionType.
+ */
+ public ConfirmationCallback(int messageType, int optionType, int defaultOption)
+ throws IllegalArgumentException
+ {
+ super();
+
+ setMessageType(messageType);
+ setOptionType(optionType, defaultOption);
+ this.defaultOption = defaultOption;
+ }
+
+ /**
+ * ConfirmationCallback with a message type, a
+ * list of options and a default option.options array, and are displayed by the
+ * {@link CallbackHandler} implementation in a manner consistent with the
+ * way preset options are displayed.options array.
+ * @throws IllegalArgumentException if messageType is not either
+ * INFORMATION, WARNING, or ERROR, if
+ * options is null, if options has a
+ * length of 0, if any element from options is
+ * null, if any element from options has a length
+ * of 0, or if defaultOption does not lie within
+ * the array boundaries of options.
+ */
+ public ConfirmationCallback(int messageType, String[] options, int defaultOption)
+ {
+ super();
+
+ setMessageType(messageType);
+ setOptions(options, defaultOption);
+ this.defaultOption = defaultOption;
+ }
+
+ /**
+ * ConfirmationCallback with a prompt, message
+ * type, an option type and a default option.prompt is null,
+ * if prompt has a length of 0, if
+ * messageType is not either WARNING, or ERROR, if optionType is
+ * not either YES_NO_OPTION, YES_NO_CANCEL_OPTION,
+ * or OK_CANCEL_OPTION, or if defaultOption does
+ * not correspond to one of the options in optionType.
+ */
+ public ConfirmationCallback(String prompt, int messageType, int optionType,
+ int defaultOption)
+ {
+ super();
+
+ setPrompt(prompt);
+ setMessageType(messageType);
+ setOptionType(optionType, defaultOption);
+ this.defaultOption = defaultOption;
+ }
+
+ /**
+ * ConfirmationCallback with a prompt, message
+ * type, a list of options and a default option.options array, and are displayed by the
+ * {@link CallbackHandler} implementation in a manner consistent with the
+ * way preset options are displayed.options array.
+ * @throws IllegalArgumentException if prompt is null,
+ * if prompt has a length of 0, if
+ * messageType is not either WARNING, or ERROR, if options is
+ * null, if options has a length of 0,
+ * if any element from options is null, if any
+ * element from options has a length of 0, or if
+ * defaultOption does not lie within the array boundaries of
+ * options.
+ */
+ public ConfirmationCallback(String prompt, int messageType, String[] options,
+ int defaultOption)
+ {
+ super();
+
+ setPrompt(prompt);
+ setMessageType(messageType);
+ setOptions(options, defaultOption);
+ this.defaultOption = defaultOption;
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Get the prompt.
+ *
+ * @return the prompt, or null if this
+ * ConfirmationCallback was instantiated without a prompt.
+ */
+ public String getPrompt()
+ {
+ return prompt;
+ }
+
+ /**
+ * Get the message type.
+ *
+ * @return the message type (INFORMATION, WARNING or ERROR).
+ */
+ public int getMessageType()
+ {
+ return messageType;
+ }
+
+ /**
+ * ConfirmationCallback was instantiated with options
+ * instead of an optionType. In this case, invoke the
+ * {@link #getOptions()} method to determine which confirmation options to
+ * display.ConfirmationCallback was instantiated with options
+ * instead of an optionType.
+ */
+ public int getOptionType()
+ {
+ if (options != null)
+ {
+ return UNSPECIFIED_OPTION;
+ }
+ return optionType;
+ }
+
+ /**
+ * Get the confirmation options.
+ *
+ * @return the list of confirmation options, or null if this
+ * ConfirmationCallback was instantiated with an
+ * optionType instead of options.
+ */
+ public String[] getOptions()
+ {
+ return options;
+ }
+
+ /**
+ * Get the default option.
+ *
+ * @return the default option, represented as YES, NO,
+ * OK or CANCEL if an optionType was
+ * specified to the constructor of this ConfirmationCallback.
+ * Otherwise, this method returns the default option as an index into the
+ * options array specified to the constructor of this
+ * ConfirmationCallback.
+ */
+ public int getDefaultOption()
+ {
+ return defaultOption;
+ }
+
+ /**
+ * Set the selected confirmation option.
+ *
+ * @param selection the selection represented as YES,
+ * NO, OK or CANCEL if an
+ * optionType was specified to the constructor of this
+ * ConfirmationCallback. Otherwise, the selection
+ * represents the index into the options array specified to the
+ * constructor of this ConfirmationCallback.
+ * @see #getSelectedIndex()
+ */
+ public void setSelectedIndex(int selection)
+ {
+ if (options != null)
+ {
+ setOptions(options, selection);
+ }
+ else
+ {
+ setOptionType(optionType, selection);
+ }
+ }
+
+ /**
+ * Get the selected confirmation option.
+ *
+ * @return the selected confirmation option represented as YES,
+ * NO, OK or CANCEL if an
+ * optionType was specified to the constructor of this
+ * ConfirmationCallback. Otherwise, this method returns the
+ * selected confirmation option as an index into the options
+ * array specified to the constructor of this ConfirmationCallback.
+ * @see #setSelectedIndex(int)
+ */
+ public int getSelectedIndex()
+ {
+ return this.selection;
+ }
+
+ private void setMessageType(int messageType) throws IllegalArgumentException
+ {
+ switch (messageType)
+ {
+ case INFORMATION:
+ case WARNING:
+ case ERROR: this.messageType = messageType; break;
+ default: throw new IllegalArgumentException("illegal message type");
+ }
+ }
+
+ private void setOptionType(int optionType, int selectedOption)
+ throws IllegalArgumentException
+ {
+ switch (optionType)
+ {
+ case YES_NO_OPTION:
+ this.optionType = optionType;
+ switch (selectedOption)
+ {
+ case YES:
+ case NO: this.selection = selectedOption; break;
+ default: throw new IllegalArgumentException("invalid option");
+ }
+ break;
+ case YES_NO_CANCEL_OPTION:
+ this.optionType = optionType;
+ switch (selectedOption)
+ {
+ case YES:
+ case NO:
+ case CANCEL: this.selection = selectedOption; break;
+ default: throw new IllegalArgumentException("invalid option");
+ }
+ break;
+ case OK_CANCEL_OPTION:
+ this.optionType = optionType;
+ switch (selectedOption)
+ {
+ case OK:
+ case CANCEL: this.selection = selectedOption; break;
+ default: throw new IllegalArgumentException("invalid option");
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("illegal option type");
+ }
+ }
+
+ private void setOptions(String[] options, int selectedOption)
+ throws IllegalArgumentException
+ {
+ if ((selectedOption < 0) || (selectedOption > options.length - 1))
+ {
+ throw new IllegalArgumentException("invalid selection");
+ }
+ if ((options == null) || (options.length == 0))
+ {
+ throw new IllegalArgumentException("options is null or empty");
+ }
+ for (int i = 0; i < options.length; i++)
+ {
+ if ((options[i] == null) || (options[i].length() == 0))
+ {
+ throw new IllegalArgumentException("options[" + i + "] is null or empty");
+ }
+ }
+ this.options = options;
+ this.selection = selectedOption;
+ }
+
+ private void setPrompt(String prompt) throws IllegalArgumentException
+ {
+ if ((prompt == null) || (prompt.length() == 0))
+ {
+ throw new IllegalArgumentException("prompt is null or empty");
+ }
+ this.prompt = prompt;
+ }
+}
diff --git a/libjava/javax/security/auth/callback/LanguageCallback.java b/libjava/javax/security/auth/callback/LanguageCallback.java
new file mode 100644
index 00000000000..71910632b48
--- /dev/null
+++ b/libjava/javax/security/auth/callback/LanguageCallback.java
@@ -0,0 +1,101 @@
+/* LanguageCallback.java -- callback for language choices.
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.callback;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * Underlying security services instantiate and pass a LanguageCallback
+ * to the handle() method of a {@link CallbackHandler} to retrieve
+ * the {@link Locale} used for localizing text.
+ *
+ * @see CallbackHandler
+ * @version $Revision: 1.1 $
+ */
+public class LanguageCallback implements Callback, Serializable
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private Locale locale;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /** Construct a LanguageCallback. */
+ public LanguageCallback()
+ {
+ super();
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Set the retrieved Locale.
+ *
+ * @param locale the retrieved Locale.
+ * @see #getLocale()
+ */
+ public void setLocale(Locale locale)
+ {
+ this.locale = locale;
+ }
+
+ /**
+ * Get the retrieved Locale.
+ *
+ * @return the retrieved Locale, or null if no Locale could be
+ * retrieved.
+ * @see #setLocale(Locale)
+ */
+ public Locale getLocale()
+ {
+ return locale;
+ }
+}
diff --git a/libjava/javax/security/auth/callback/NameCallback.java b/libjava/javax/security/auth/callback/NameCallback.java
new file mode 100644
index 00000000000..c98edfdbea9
--- /dev/null
+++ b/libjava/javax/security/auth/callback/NameCallback.java
@@ -0,0 +1,179 @@
+/* NameCallback.java -- callback for user names.
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a NameCallback
+ * to the handle() method of a {@link CallbackHandler} to retrieve
+ * name information.
+ *
+ * @see CallbackHandler
+ * @version $Revision: 1.1 $
+ */
+public class NameCallback implements Callback, Serializable
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private String prompt;
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private String defaultName;
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private String inputName;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Construct a NameCallback with a prompt.
+ *
+ * @param prompt the prompt used to request the name.
+ * @throws IllegalArgumentException if prompt is null
+ * or if prompt has a length of 0.
+ */
+ public NameCallback(String prompt)
+ {
+ super();
+
+ setPrompt(prompt);
+ }
+
+ /**
+ * Construct a NameCallback with a prompt and default name.
+ *
+ * @param prompt the prompt used to request the information.
+ * @param defaultName the name to be used as the default name displayed with
+ * the prompt.
+ * @throws IllegalArgumentException if prompt is null
+ * or if prompt has a length of 0, if
+ * defaultName is null, or if defaultName
+ * has a length of 0.
+ */
+ public NameCallback(String prompt, String defaultName)
+ throws IllegalArgumentException
+ {
+ super();
+
+ setPrompt(prompt);
+ setDefaultName(defaultName);
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Get the prompt.
+ *
+ * @return the prompt.
+ */
+ public String getPrompt()
+ {
+ return prompt;
+ }
+
+ /**
+ * Get the default name.
+ *
+ * @return the default name, or null if this
+ * NameCallback was not instantiated with a
+ * defaultName.
+ */
+ public String getDefaultName()
+ {
+ return defaultName;
+ }
+
+ /**
+ * Set the retrieved name.
+ *
+ * @param name the retrieved name (which may be null).
+ * @see #getName()
+ */
+ public void setName(String name)
+ {
+ this.inputName = name;
+ }
+
+ /**
+ * Get the retrieved name.
+ *
+ * @return the retrieved name (which may be null)
+ * @see #setName(String)
+ */
+ public String getName()
+ {
+ return inputName;
+ }
+
+ private void setPrompt(String prompt) throws IllegalArgumentException
+ {
+ if ((prompt == null) || (prompt.length() == 0))
+ {
+ throw new IllegalArgumentException("invalid prompt");
+ }
+ this.prompt = prompt;
+ }
+
+ private void setDefaultName(String defaultName) throws IllegalArgumentException
+ {
+ if ((defaultName == null) || (defaultName.length() == 0))
+ {
+ throw new IllegalArgumentException("invalid default name");
+ }
+ this.defaultName = defaultName;
+ }
+}
diff --git a/libjava/javax/security/auth/callback/PasswordCallback.java b/libjava/javax/security/auth/callback/PasswordCallback.java
new file mode 100644
index 00000000000..5620bc5cd79
--- /dev/null
+++ b/libjava/javax/security/auth/callback/PasswordCallback.java
@@ -0,0 +1,169 @@
+/* PasswordCallback.java -- callback for passwords.
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a PasswordCallback
+ * to the handle() method of a {@link CallbackHandler} to retrieve
+ * password information.
+ *
+ * @see CallbackHandler,
+ * @version $Revision: 1.1 $
+ */
+public class PasswordCallback implements Callback, Serializable
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private String prompt;
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private boolean echoOn;
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private char[] inputPassword;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Construct a PasswordCallback with a prompt and a boolean
+ * specifying whether the password should be displayed as it is being typed.
+ *
+ * @param prompt the prompt used to request the password.
+ * @param echoOn true if the password should be displayed as it
+ * is being typed.
+ * @throws IllegalArgumentException if prompt is null
+ * or if prompt has a length of 0.
+ */
+ public PasswordCallback(String prompt, boolean echoOn)
+ {
+ super();
+
+ setPrompt(prompt);
+ this.echoOn = echoOn;
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Get the prompt.
+ *
+ * @return the prompt.
+ */
+ public String getPrompt()
+ {
+ return prompt;
+ }
+
+ /**
+ * Return whether the password should be displayed as it is being typed.
+ *
+ * @return the whether the password should be displayed as it is being typed.
+ */
+ public boolean isEchoOn()
+ {
+ return echoOn;
+ }
+
+ /**
+ * null.
+ * @see #getPassword()
+ */
+ public void setPassword(char[] password)
+ {
+ inputPassword = (password == null ? null : (char[]) password.clone());
+ }
+
+ /**
+ * null.
+ * @see #setPassword(char[])
+ */
+ public char[] getPassword()
+ {
+ return (inputPassword == null ? null : (char[]) inputPassword.clone());
+ }
+
+ /** Clear the retrieved password. */
+ public void clearPassword()
+ {
+ if (inputPassword != null)
+ {
+ for (int i = 0; i < inputPassword.length; i++)
+ {
+ inputPassword[i] = '\0';
+ }
+ inputPassword = null;
+ }
+ }
+
+ private void setPrompt(String prompt) throws IllegalArgumentException
+ {
+ if ((prompt == null) || (prompt.length() == 0))
+ {
+ throw new IllegalArgumentException("invalid prompt");
+ }
+ this.prompt = prompt;
+ }
+}
diff --git a/libjava/javax/security/auth/callback/TextInputCallback.java b/libjava/javax/security/auth/callback/TextInputCallback.java
new file mode 100644
index 00000000000..55c1aa2534d
--- /dev/null
+++ b/libjava/javax/security/auth/callback/TextInputCallback.java
@@ -0,0 +1,178 @@
+/* TextInputCallback.java -- callbacks for user input.
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a TextInputCallback
+ * to the handle() method of a {@link CallbackHandler} to retrieve
+ * generic text information.
+ *
+ * @see CallbackHandler
+ * @version $Revision: 1.1 $
+ */
+public class TextInputCallback implements Callback, Serializable
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private String prompt;
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private String defaultText;
+
+ /**
+ * @serial
+ * @since 1.4
+ */
+ private String inputText;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Construct a TextInputCallback with a prompt.
+ *
+ * @param prompt the prompt used to request the information.
+ * @throws IllegalArgumentException if prompt is null
+ * or if prompt has a length of 0.
+ */
+ public TextInputCallback(String prompt) throws IllegalArgumentException
+ {
+ super();
+
+ setPrompt(prompt);
+ }
+
+ /**
+ * Construct a TextInputCallback with a prompt and default
+ * input value.
+ *
+ * @param prompt the prompt used to request the information.
+ * @param defaultText the text to be used as the default text displayed with
+ * the prompt.
+ * @throws IllegalArgumentException if prompt is null,
+ * if prompt has a length of 0, if
+ * defaultText is null or if defaultText
+ * has a length of 0.
+ */
+ public TextInputCallback(String prompt, String defaultText)
+ throws IllegalArgumentException
+ {
+ super();
+
+ setPrompt(prompt);
+ setDefaultText(defaultText);
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Get the prompt.
+ *
+ * @return the prompt.
+ */
+ public String getPrompt()
+ {
+ return prompt;
+ }
+
+ /**
+ * Get the default text.
+ *
+ * @return the default text, or null if this
+ * TextInputCallback was not instantiated with
+ * defaultText.
+ */
+ public String getDefaultText()
+ {
+ return defaultText;
+ }
+
+ /**
+ * Set the retrieved text.
+ *
+ * @param text the retrieved text, which may be null.
+ */
+ public void setText(String text)
+ {
+ this.inputText = text;
+ }
+
+ /**
+ * Get the retrieved text.
+ *
+ * @return the retrieved text, which may be null.
+ */
+ public String getText()
+ {
+ return inputText;
+ }
+
+ private void setPrompt(String prompt) throws IllegalArgumentException
+ {
+ if ((prompt == null) || (prompt.length() == 0))
+ {
+ throw new IllegalArgumentException("invalid prompt");
+ }
+ this.prompt = prompt;
+ }
+
+ private void setDefaultText(String defaultText) throws IllegalArgumentException
+ {
+ if ((defaultText == null) || (defaultText.length() == 0))
+ {
+ throw new IllegalArgumentException("invalid default text");
+ }
+ this.defaultText = defaultText;
+ }
+}
diff --git a/libjava/javax/security/auth/callback/TextOutputCallback.java b/libjava/javax/security/auth/callback/TextOutputCallback.java
new file mode 100644
index 00000000000..380a5ef60f0
--- /dev/null
+++ b/libjava/javax/security/auth/callback/TextOutputCallback.java
@@ -0,0 +1,141 @@
+/* TextOutputCallback.java -- callback for text output.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.callback;
+
+import java.io.Serializable;
+
+/**
+ * TextOutputCallback to the handle() method of a
+ * {@link CallbackHandler} to display information messages, warning messages and
+ * error messages.TextOutputCallback with a message type and
+ * message to be displayed.messageType is not either
+ * INFORMATION, WARNING or ERROR, if
+ * message is null, or if message has
+ * a length of 0.
+ */
+ public TextOutputCallback(int messageType, String message)
+ throws IllegalArgumentException
+ {
+ switch (messageType)
+ {
+ case INFORMATION:
+ case WARNING:
+ case ERROR: this.messageType = messageType; break;
+ default: throw new IllegalArgumentException("invalid message type");
+ }
+
+ setMessage(message);
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * messageType.message to be displayed.UnsupportedCallbackException with no detail
+ * message.
+ *
+ * @param callback the unrecognized {@link Callback}.
+ */
+ public UnsupportedCallbackException(Callback callback)
+ {
+ super();
+
+ this.callback = callback;
+ }
+
+ /**
+ * Constructs an UnsupportedCallbackException with the specified
+ * detail message. A detail message is a {@link String} that describes this
+ * particular exception.
+ *
+ * @param callback the unrecognized {@link Callback}.
+ * @param msg the detail message.
+ */
+ public UnsupportedCallbackException(Callback callback, String msg)
+ {
+ super(msg);
+
+ this.callback = callback;
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Get the unrecognized {@link Callback}.
+ *
+ * @return the unrecognized {@link Callback}.
+ */
+ public Callback getCallback()
+ {
+ return this.callback;
+ }
+}
diff --git a/libjava/javax/security/auth/login/AccountExpiredException.java b/libjava/javax/security/auth/login/AccountExpiredException.java
new file mode 100644
index 00000000000..e8e331347be
--- /dev/null
+++ b/libjava/javax/security/auth/login/AccountExpiredException.java
@@ -0,0 +1,64 @@
+/* AccountExpiredException.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.login;
+
+/**
+ * An exception that signals that an attempt was made to login to an account
+ * that has expired.
+ */
+public class AccountExpiredException extends LoginException
+{
+
+ // Constant.
+ // -------------------------------------------------------------------------
+
+ private static final long serialVersionUID = -6064064890162661560L;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public AccountExpiredException()
+ {
+ }
+
+ public AccountExpiredException (String message)
+ {
+ super (message);
+ }
+}
diff --git a/libjava/javax/security/auth/login/AppConfigurationEntry.java b/libjava/javax/security/auth/login/AppConfigurationEntry.java
new file mode 100644
index 00000000000..1879a68c1e8
--- /dev/null
+++ b/libjava/javax/security/auth/login/AppConfigurationEntry.java
@@ -0,0 +1,135 @@
+/* AppConfigurationEntry.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.login;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AppConfigurationEntry
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private final String loginModuleName;
+ private final LoginModuleControlFlag controlFlag;
+ private final Map options;
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ public AppConfigurationEntry (final String loginModuleName,
+ final LoginModuleControlFlag controlFlag,
+ final Map options)
+ {
+ if (loginModuleName == null || loginModuleName.length() == 0)
+ throw new IllegalArgumentException ("module name cannot be null nor empty");
+ if (LoginModuleControlFlag.OPTIONAL != controlFlag &&
+ LoginModuleControlFlag.REQUIRED != controlFlag &&
+ LoginModuleControlFlag.REQUISITE != controlFlag &&
+ LoginModuleControlFlag.SUFFICIENT != controlFlag)
+ throw new IllegalArgumentException ("invalid controlFlag");
+ if (options == null)
+ throw new IllegalArgumentException ("options cannot be null");
+ this.loginModuleName = loginModuleName;
+ this.controlFlag = controlFlag;
+ this.options = Collections.unmodifiableMap (new HashMap (options));
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public LoginModuleControlFlag getControlFlag()
+ {
+ return controlFlag;
+ }
+
+ public String getLoginModuleName()
+ {
+ return loginModuleName;
+ }
+
+ public Map getOptions()
+ {
+ return options;
+ }
+
+// Inner class.
+ // -------------------------------------------------------------------------
+
+ public static class LoginModuleControlFlag
+ {
+
+ // Constants.
+ // -----------------------------------------------------------------------
+
+ public static final LoginModuleControlFlag OPTIONAL = new LoginModuleControlFlag();
+ public static final LoginModuleControlFlag REQUIRED = new LoginModuleControlFlag();
+ public static final LoginModuleControlFlag REQUISITE = new LoginModuleControlFlag();
+ public static final LoginModuleControlFlag SUFFICIENT = new LoginModuleControlFlag();
+
+ // Constructor.
+ // -----------------------------------------------------------------------
+
+ private LoginModuleControlFlag()
+ {
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------------
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer (LoginModuleControlFlag.class.getName());
+ buf.append ('.');
+ if (this == OPTIONAL)
+ buf.append ("OPTIONAL");
+ else if (this == REQUIRED)
+ buf.append ("REQUIRED");
+ else if (this == REQUISITE)
+ buf.append ("REQUISITE");
+ else if (this == SUFFICIENT)
+ buf.append ("SUFFICIENT");
+ else
+ buf.append ("HARVEY_THE_RABBIT");
+ return buf.toString();
+ }
+ }
+}
diff --git a/libjava/javax/security/auth/login/Configuration.java b/libjava/javax/security/auth/login/Configuration.java
new file mode 100644
index 00000000000..4a55013ca2b
--- /dev/null
+++ b/libjava/javax/security/auth/login/Configuration.java
@@ -0,0 +1,109 @@
+/* Configuration.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.login;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
+
+import javax.security.auth.AuthPermission;
+
+public abstract class Configuration
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private static Configuration config;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ protected Configuration()
+ {
+ }
+
+ // Class methods.
+ // -------------------------------------------------------------------------
+
+ public static synchronized Configuration getConfiguration()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission (new AuthPermission ("getLoginConfiguration"));
+ if (config == null)
+ {
+ String conf = (String) AccessController.doPrivileged
+ (new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return Security.getProperty ("login.configuration.provider");
+ }
+ });
+ try
+ {
+ if (conf != null)
+ config = (Configuration) Class.forName (conf).newInstance();
+ else
+ config = new NullConfiguration();
+ }
+ catch (Exception x)
+ {
+ config = new NullConfiguration();
+ }
+ }
+ return config;
+ }
+
+ public static synchronized void setConfiguration (Configuration config)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission (new AuthPermission ("setLoginConfiguration"));
+ Configuration.config = config;
+ }
+
+ // Abstract methods.
+ // -------------------------------------------------------------------------
+
+ public abstract AppConfigurationEntry[] getAppConfigurationEntry (String applicationName);
+
+ public abstract void refresh();
+}
diff --git a/libjava/javax/security/auth/login/CredentialExpiredException.java b/libjava/javax/security/auth/login/CredentialExpiredException.java
new file mode 100644
index 00000000000..df643ba6990
--- /dev/null
+++ b/libjava/javax/security/auth/login/CredentialExpiredException.java
@@ -0,0 +1,64 @@
+/* CredentialExpiredException.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.login;
+
+/**
+ * An exception that signals an attempt to login with a credential that
+ * has expired.
+ */
+public class CredentialExpiredException extends LoginException
+{
+
+ // Constant.
+ // -------------------------------------------------------------------------
+
+ private static final long serialVersionUID = -5344739593859737937L;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public CredentialExpiredException()
+ {
+ }
+
+ public CredentialExpiredException (String message)
+ {
+ super (message);
+ }
+}
diff --git a/libjava/javax/security/auth/login/FailedLoginException.java b/libjava/javax/security/auth/login/FailedLoginException.java
new file mode 100644
index 00000000000..384ade08427
--- /dev/null
+++ b/libjava/javax/security/auth/login/FailedLoginException.java
@@ -0,0 +1,63 @@
+/* FailedLoginException.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.login;
+
+/**
+ * An exception that signals that an attempt to login was unsuccessful.
+ */
+public class FailedLoginException extends LoginException
+{
+
+ // Constant.
+ // -------------------------------------------------------------------------
+
+ private static final long serialVersionUID = 802556922354616286L;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public FailedLoginException()
+ {
+ }
+
+ public FailedLoginException (String message)
+ {
+ super (message);
+ }
+}
diff --git a/libjava/javax/security/auth/login/LoginContext.java b/libjava/javax/security/auth/login/LoginContext.java
new file mode 100644
index 00000000000..da88e841282
--- /dev/null
+++ b/libjava/javax/security/auth/login/LoginContext.java
@@ -0,0 +1,44 @@
+/* LoginContext.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.login;
+
+public class LoginContext
+{
+
+}
diff --git a/libjava/javax/security/auth/login/LoginException.java b/libjava/javax/security/auth/login/LoginException.java
new file mode 100644
index 00000000000..878120381b5
--- /dev/null
+++ b/libjava/javax/security/auth/login/LoginException.java
@@ -0,0 +1,65 @@
+/* LoginException.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.login;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * A general exception during authentication and authorization.
+ */
+public class LoginException extends GeneralSecurityException
+{
+
+ // Constant.
+ // -------------------------------------------------------------------------
+
+ private static final long serialVersionUID = -4679091624035232488L;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public LoginException()
+ {
+ }
+
+ public LoginException (String message)
+ {
+ super (message);
+ }
+}
diff --git a/libjava/javax/security/auth/login/NullConfiguration.java b/libjava/javax/security/auth/login/NullConfiguration.java
new file mode 100644
index 00000000000..e1c99037f96
--- /dev/null
+++ b/libjava/javax/security/auth/login/NullConfiguration.java
@@ -0,0 +1,64 @@
+/* NullConfiguration.java -- no-op default login configuration.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.login;
+
+import javax.security.auth.AuthPermission;
+
+final class NullConfiguration extends Configuration
+{
+
+ // Contructor.
+ // -------------------------------------------------------------------------
+
+ NullConfiguration()
+ {
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public AppConfigurationEntry[] getAppConfigurationEntry (String applicationName)
+ {
+ return null;
+ }
+
+ public void refresh()
+ {
+ }
+}
diff --git a/libjava/javax/security/auth/x500/X500PrivateCredential.java b/libjava/javax/security/auth/x500/X500PrivateCredential.java
new file mode 100644
index 00000000000..fb3a5ef40b7
--- /dev/null
+++ b/libjava/javax/security/auth/x500/X500PrivateCredential.java
@@ -0,0 +1,148 @@
+/* X500PrivateCredential.java -- certificate and private key pair.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.x500;
+
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import javax.security.auth.Destroyable;
+
+/**
+ * A pairing of a {@link X509Certificate} and its corresponding {@link
+ * PrivateKey}, with an optional keystore alias.
+ */
+public final class X500PrivateCredential implements Destroyable
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private PrivateKey key;
+ private X509Certificate certificate;
+ private String alias;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Creates a new private credential with no associated keystore alias.
+ *
+ * @param certificate The X.509 certificate.
+ * @param key The private key.
+ * @throws IllegalArgumentException If either parameter is null.
+ */
+ public X500PrivateCredential (X509Certificate certificate, PrivateKey key)
+ {
+ if (certificate == null || key == null)
+ throw new IllegalArgumentException();
+ this.certificate = certificate;
+ this.key = key;
+ }
+
+ /**
+ * Creates a new private credential with a keystore alias.
+ *
+ * @param certificate The X.509 certificate.
+ * @param key The private key.
+ * @param alias The keystore alias for this credential.
+ * @throws IllegalArgumentException If any parameter is null.
+ */
+ public X500PrivateCredential (X509Certificate certificate, PrivateKey key,
+ String alias)
+ {
+ this (certificate, key);
+ if (alias == null)
+ throw new IllegalArgumentException();
+ this.alias = alias;
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the certificate of this credential.
+ *
+ * @return The certificate of this credential.
+ */
+ public X509Certificate getCertificate()
+ {
+ return certificate;
+ }
+
+ /**
+ * Returns the private key of this credential.
+ *
+ * @return The private key of this credential.
+ */
+ public PrivateKey getPrivateKey()
+ {
+ return key;
+ }
+
+ /**
+ * Returns the keystore alias of this credential, or null if not present.
+ *
+ * @return The keystore alias, or null.
+ */
+ public String getAlias()
+ {
+ return alias;
+ }
+
+ /**
+ * Destroy the sensitive data of this credential, setting the certificate,
+ * private key, and keystore alias to null.
+ */
+ public void destroy()
+ {
+ certificate = null;
+ key = null;
+ alias = null;
+ }
+
+ /**
+ * Tells whether or not this credential has been destroyed, and that
+ * the certificate and private key fields are null.
+ *
+ * @return True if this object has been destroyed.
+ */
+ public boolean isDestroyed()
+ {
+ return certificate == null && key == null;
+ }
+}
diff --git a/libjava/javax/security/cert/Certificate.java b/libjava/javax/security/cert/Certificate.java
new file mode 100644
index 00000000000..8090817fcf4
--- /dev/null
+++ b/libjava/javax/security/cert/Certificate.java
@@ -0,0 +1,176 @@
+/* Certificate.java -- base class of public-key certificates.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.cert;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.SignatureException;
+
+import java.util.Arrays;
+import java.util.zip.Adler32;
+
+/**
+ * AuthenticationException does not
+ * mean that the failure was not due to an authentication error. A SASL
+ * mechanism implementation might throw the more general {@link SaslException}
+ * instead of AuthenticationException if it is unable to determine
+ * the nature of the failure, or if does not want to disclose the nature of the
+ * failure, for example, due to security reasons.AuthenticationException. The
+ * root exception and the detailed message are null.
+ */
+ public AuthenticationException()
+ {
+ super();
+ }
+
+ /**
+ * Constructs a new instance of AuthenticationException with a
+ * detailed message. The root exception is null.
+ *
+ * @param detail a possibly null string containing details of
+ * the exception.
+ * @see Throwable#getMessage()
+ */
+ public AuthenticationException(String detail)
+ {
+ super(detail);
+ }
+
+ /**
+ * Constructs a new instance of AuthenticationException with a
+ * detailed message and a root exception.
+ *
+ * @param detail a possibly null string containing details of
+ * the exception.
+ * @param ex a possibly null root exception that caused this
+ * exception.
+ * @see Throwable#getMessage()
+ * @see SaslException#getCause()
+ */
+ public AuthenticationException(String detail, Throwable ex)
+ {
+ super(detail, ex);
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+}
diff --git a/libjava/javax/security/sasl/AuthorizeCallback.java b/libjava/javax/security/sasl/AuthorizeCallback.java
new file mode 100644
index 00000000000..77fe78698ad
--- /dev/null
+++ b/libjava/javax/security/sasl/AuthorizeCallback.java
@@ -0,0 +1,171 @@
+/* AuthorizeCallback.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpathis free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpathis 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+import javax.security.auth.callback.Callback;
+
+/**
+ * This callback is used by {@link SaslServer} to determine whether one entity
+ * (identified by an authenticated authentication ID) can act on behalf of
+ * another entity (identified by an authorization ID).
+ */
+public class AuthorizeCallback implements Callback
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /** @serial The (authenticated) authentication id to check. */
+ private String authenticationID = null;
+
+ /** @serial The authorization id to check. */
+ private String authorizationID = null;
+
+ /**
+ * @serial The id of the authorized entity. If null, the id of the authorized
+ * entity is authorizationID.
+ */
+ private String authorizedID = null;
+
+ /**
+ * @serial A flag indicating whether the authentication id is allowed to act
+ * on behalf of the authorization id.
+ */
+ private boolean authorized = false;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Constructs an instance of AuthorizeCallback.
+ *
+ * @param authnID the (authenticated) authentication ID.
+ * @param authzID the authorization ID.
+ */
+ public AuthorizeCallback(String authnID, String authzID)
+ {
+ super();
+
+ this.authenticationID = authnID;
+ this.authorizationID = authzID;
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the authentication ID to check.
+ *
+ * @return the authentication ID to check
+ */
+ public String getAuthenticationID()
+ {
+ return authenticationID;
+ }
+
+ /**
+ * Returns the authorization ID to check.
+ *
+ * @return the authorization ID to check.
+ */
+ public String getAuthorizationID()
+ {
+ return authorizationID;
+ }
+
+ /**
+ * Determines if the identity represented by authentication ID is allowed to
+ * act on behalf of the authorization ID.
+ *
+ * @return true if authorization is allowed; false
+ * otherwise.
+ * @see #setAuthorized(boolean)
+ * @see #getAuthorizedID()
+ */
+ public boolean isAuthorized()
+ {
+ return authorized;
+ }
+
+ /**
+ * Sets if authorization is allowed or not.
+ *
+ * @param authorized true if authorization is allowed;
+ * false otherwise.
+ * @see #isAuthorized()
+ * @see #setAuthorizedID(String)
+ */
+ public void setAuthorized(boolean authorized)
+ {
+ this.authorized = authorized;
+ }
+
+ /**
+ * Returns the ID of the authorized user.
+ *
+ * @return the ID of the authorized user. null means the
+ * authorization failed.
+ * @see #setAuthorized(boolean)
+ * @see #setAuthorizedID(String)
+ */
+ public String getAuthorizedID()
+ {
+ if (!authorized)
+ {
+ return null;
+ }
+ return (authorizedID != null ? authorizedID : authorizationID);
+ }
+
+ /**
+ * Sets the ID of the authorized entity. Called by handler only when the ID
+ * is different from {@link #getAuthorizationID()}. For example, the ID might
+ * need to be canonicalized for the environment in which it will be used.
+ *
+ * @see #setAuthorized(boolean)
+ * @see #getAuthorizedID()
+ */
+ public void setAuthorizedID(String id)
+ {
+ this.authorizedID = id;
+ }
+}
diff --git a/libjava/javax/security/sasl/RealmCallback.java b/libjava/javax/security/sasl/RealmCallback.java
new file mode 100644
index 00000000000..49bc08ae2ec
--- /dev/null
+++ b/libjava/javax/security/sasl/RealmCallback.java
@@ -0,0 +1,75 @@
+/* RealmCallback.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+import javax.security.auth.callback.TextInputCallback;
+
+/**
+ * This callback is used by {@link SaslClient} and {@link SaslServer} to
+ * retrieve realm information.
+ */
+public class RealmCallback extends TextInputCallback
+{
+
+ /**
+ * Constructs a RealmCallback with a prompt.
+ *
+ * @param prompt the non-null prompt to use to request the realm information.
+ * @throws IllegalArgumentException if prompt is null
+ * or empty.
+ */
+ public RealmCallback(String prompt)
+ {
+ super(prompt);
+ }
+
+ /**
+ * Constructs a RealmCallback with a prompt and default realm
+ * information.
+ *
+ * @param prompt the non-null prompt to use to request the realm information.
+ * @param defaultRealmInfo the non-null default realm information to use.
+ * @throws IllegalArgumentException if prompt is null
+ * or empty, or if defaultRealm is empty or null.
+ */
+ public RealmCallback(String prompt, String defaultRealmInfo)
+ {
+ super(prompt, defaultRealmInfo);
+ }
+}
diff --git a/libjava/javax/security/sasl/RealmChoiceCallback.java b/libjava/javax/security/sasl/RealmChoiceCallback.java
new file mode 100644
index 00000000000..2e00407610f
--- /dev/null
+++ b/libjava/javax/security/sasl/RealmChoiceCallback.java
@@ -0,0 +1,71 @@
+/* RealmChoiceCallback.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+import javax.security.auth.callback.ChoiceCallback;
+
+/**
+ * This callback is used by {@link SaslClient} and {@link SaslServer} to obtain
+ * a realm given a list of realm choices.
+ */
+public class RealmChoiceCallback extends ChoiceCallback
+{
+
+ /**
+ * Constructs a RealmChoiceCallback with a prompt, a list of
+ * choices and a default choice.
+ *
+ * @param prompt the non-null prompt to use to request the realm.
+ * @param choices the non-null list of realms to choose from.
+ * @param defaultChoice the choice to be used as the default when the list of
+ * choices is displayed. It is an index into the choices array.
+ * @param multiple true if multiple choices allowed;
+ * false otherwise.
+ * @throws IllegalArgumentException if prompt is null
+ * or empty, if choices has a length of 0, if any
+ * element from choices is null or empty, or if
+ * defaultChoice does not fall within the array boundary of
+ * choices.
+ */
+ public RealmChoiceCallback(String prompt, String[] choices, int defaultChoice,
+ boolean multiple)
+ {
+ super(prompt, choices, defaultChoice, multiple);
+ }
+}
diff --git a/libjava/javax/security/sasl/Sasl.java b/libjava/javax/security/sasl/Sasl.java
new file mode 100644
index 00000000000..2174692f4b4
--- /dev/null
+++ b/libjava/javax/security/sasl/Sasl.java
@@ -0,0 +1,691 @@
+/* Sasl.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+import java.security.Security;
+import java.security.Provider;
+
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ *
+ *SaslClient sc =
+ * Sasl.createSaslClient(mechanisms, authorizationID, protocol,
+ * serverName, props, callbackHandler);
+ *
+ *
+ *
+ *SaslServer ss =
+ * Sasl.createSaslServer(mechanism, protocol, serverName, props,
+ * callbackHandler);
+ *
+ */
+public class Sasl
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /**
+ *
+ *
+ *
+ * "auth" - authentication only,"auth-int" - authentication plus integrity
+ * protection,"auth-conf" - authentication plus integrity and
+ * confidentiality protection."auth"."javax.security.sasl.qop".
+ *
+ *
+ * "low","medium","high"."high,medium,low"."javax.security.sasl.strength".
+ * "true" if the server
+ * must authenticate the to client; "false" otherwise. The
+ * default is "false"."javax.security.sasl.server.authentication"."javax.security.sasl.maxbuffer".
+ * "javax.security.sasl.rawsendsize".
+ * "true" if such mechanisms are not
+ * permitted; "false" if such mechanisms are permitted. The
+ * default is "false"."javax.security.sasl.policy.noplaintext".
+ * "true" if mechanisms susceptible to active attacks are not
+ * permitted; "false" if such mechanisms are permitted. The
+ * default is "false"."javax.security.sasl.policy.noactive".
+ * "true" if mechanisms susceptible to dictionary attacks are
+ * not permitted; "false" if such mechanisms are permitted. The
+ * default is "false"."javax.security.sasl.policy.nodictionary".
+ * "true"
+ * if mechanisms that accept anonymous login are not permitted; "false"
+ * if such mechanisms are permitted. The default is "false".
+ * "javax.security.sasl.policy.noanonymous".
+ * "true"
+ * if mechanisms that implement forward secrecy between sessions are
+ * required; "false" if such mechanisms are not required. The
+ * default is "false"."javax.security.sasl.policy.forward".
+ * "true" if
+ * mechanisms that pass client credentials are required; "false"
+ * if such mechanisms are not required. The default is "false".
+ *
The value of this constant is "javax.security.sasl.policy.credentials".
+ *
The name of a property that specifies whether to reuse previously
+ * authenticated session information. The property contains "true"
+ * if the mechanism implementation may attempt to reuse previously
+ * authenticated session information; it contains "false" if the
+ * implementation must not reuse previously authenticated session information.
+ * A setting of "true" serves only as a hint; it does not
+ * necessarily entail actual reuse because reuse might not be possible due to
+ * a number of reasons, including, but not limited to, lack of mechanism
+ * support for reuse, expiration of reusable information, and the peer's
+ * refusal to support reuse. The property's default value is "false".
+ *
The value of this constant is "javax.security.sasl.reuse".
+ * Note that all other parameters and properties required to create a SASL
+ * client/server instance must be provided regardless of whether this
+ * property has been supplied. That is, you cannot supply any less
+ * information in anticipation of reuse. Mechanism implementations that
+ * support reuse might allow customization of its implementation for factors
+ * such as cache size, timeouts, and criteria for reuseability. Such
+ * customizations are implementation-dependent.
Creates a {@link SaslClient} for the specified mechanism.
+ * + *This method uses the JCA Security Provider Framework, described in the + * "Java Cryptography Architecture API Specification & Reference", for + * locating and selecting a {@link SaslClient} implementation.
+ * + *First, it obtains an ordered list of {@link SaslClientFactory}
+ * instances from the registered security providers for the
+ * "SaslClientFactory" service and the specified mechanism. It
+ * then invokes createSaslClient() on each factory instance on
+ * the list until one produces a non-null {@link SaslClient} instance. It
+ * returns the non-null {@link SaslClient} instance, or null if
+ * the search fails to produce a non-null {@link SaslClient} instance.
A security provider for SaslClientFactory registers with
+ * the JCA Security Provider Framework keys of the form:
+ * SaslClientFactory.mechanism_name + *+ * + *
and values that are class names of implementations of {@link + * SaslClientFactory}.
+ * + *For example, a provider that contains a factory class,
+ * com.wiz.sasl.digest.ClientFactory, that supports the
+ * "DIGEST-MD5" mechanism would register the following entry
+ * with the JCA:
+ * SaslClientFactory.DIGEST-MD5 com.wiz.sasl.digest.ClientFactory + *+ * + *
See the "Java Cryptography Architecture API Specification & + * Reference" for information about how to install and configure security + * service providers.
+ * + * @param mechanisms the non-null list of mechanism names to try. Each is the + * IANA-registered name of a SASL mechanism. (e.g. "GSSAPI", "CRAM-MD5"). + * @param authorizationID the possiblynull protocol-dependent
+ * identification to be used for authorization. If null or
+ * empty, the server derives an authorization ID from the client's
+ * authentication credentials. When the SASL authentication completes
+ * successfully, the specified entity is granted access.
+ * @param protocol the non-null string name of the protocol for which the
+ * authentication is being performed (e.g. "ldap").
+ * @param serverName the non-null fully-qualified host name of the server to
+ * authenticate to.
+ * @param props the possibly null set of properties used to select the SASL
+ * mechanism and to configure the authentication exchange of the selected
+ * mechanism. For example, if props contains the {@link Sasl#POLICY_NOPLAINTEXT}
+ * property with the value "true", then the selected SASL
+ * mechanism must not be susceptible to simple plain passive attacks. In
+ * addition to the standard properties declared in this class, other,
+ * possibly mechanism-specific, properties can be included. Properties not
+ * relevant to the selected mechanism are ignored.
+ * @param cbh the possibly null callback handler to used by the
+ * SASL mechanisms to get further information from the application/library to
+ * complete the authentication. For example, a SASL mechanism might require
+ * the authentication ID, password and realm from the caller. The
+ * authentication ID is requested by using a
+ * {@link javax.security.auth.callback.NameCallback}. The password is
+ * requested by using a {@link javax.security.auth.callback.PasswordCallback}.
+ * The realm is requested by using a {@link RealmChoiceCallback} if there is
+ * a list of realms to choose from, and by using a {@link RealmCallback} if
+ * the realm must be entered.
+ * @return a possibly null {@link SaslClient} created using the
+ * parameters supplied. If null, the method could not find a
+ * {@link SaslClientFactory} that will produce one.
+ * @throws SaslException if a {@link SaslClient} cannot be created because
+ * of an error.
+ */
+ public static SaslClient createSaslClient(String[] mechanisms,
+ String authorizationID,
+ String protocol,
+ String serverName, Map props,
+ CallbackHandler cbh)
+ throws SaslException
+ {
+ if (mechanisms == null)
+ {
+ return null;
+ }
+ Provider[] providers = Security.getProviders();
+ if (providers == null || providers.length == 0)
+ {
+ return null;
+ }
+
+ SaslClient result = null;
+ SaslClientFactory factory = null;
+ String m, clazz = null, upper, alias;
+ int j;
+ Provider p;
+ for (int i = 0; i < mechanisms.length; i++)
+ {
+ m = mechanisms[i];
+ if (m == null)
+ continue;
+ for (j = 0; j < providers.length; j++)
+ {
+ p = providers[j];
+ if (p != null)
+ {
+ // try the name as is
+ clazz = p.getProperty(CLIENT_FACTORY_SVC + m);
+ if (clazz == null) // try all uppercase
+ {
+ upper = m.toUpperCase();
+ clazz = p.getProperty(CLIENT_FACTORY_SVC + upper);
+ if (clazz == null) // try if it's an alias
+ {
+ alias = p.getProperty(ALIAS + CLIENT_FACTORY_SVC + m);
+ if (alias == null) // try all-uppercase alias name
+ {
+ alias = p.getProperty(ALIAS + CLIENT_FACTORY_SVC + upper);
+ if (alias == null) // spit the dummy
+ continue;
+ }
+ clazz = p.getProperty(CLIENT_FACTORY_SVC + alias);
+ }
+ }
+ if (clazz == null)
+ continue;
+ else
+ clazz = clazz.trim();
+ }
+
+ try
+ {
+ result = null;
+ factory = (SaslClientFactory) Class.forName(clazz).newInstance();
+ result = factory.createSaslClient(mechanisms, authorizationID,
+ protocol, serverName, props, cbh);
+ }
+ catch (ClassCastException ignored) // ignore instantiation exceptions
+ {
+ }
+ catch (ClassNotFoundException ignored)
+ {
+ }
+ catch (InstantiationException ignored)
+ {
+ }
+ catch (IllegalAccessException ignored)
+ {
+ }
+ if (result != null)
+ return result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets an enumeration of known factories for producing a {@link SaslClient}
+ * instance. This method uses the same sources for locating factories as
+ * createSaslClient().
+ *
+ * @return a non-null {@link Enumeration} of known factories for producing a
+ * {@link SaslClient} instance.
+ * @see #createSaslClient(String[],String,String,String,Map,CallbackHandler)
+ */
+ public static Enumeration getSaslClientFactories()
+ {
+ Vector result = new Vector();
+ HashSet names = new HashSet();
+ Provider[] providers = Security.getProviders();
+ Iterator it;
+ if (providers == null)
+ {
+ Provider p;
+ String key;
+ for (int i = 0; i < providers.length; i++)
+ {
+ p = providers[i];
+ for (it = p.keySet().iterator(); it.hasNext(); )
+ {
+ key = (String) it.next();
+ // add key's binding (a) it is a class of a client factory,
+ // and (b) the key does not include blanks
+ if (key.startsWith(CLIENT_FACTORY_SVC) && key.indexOf(" ") == -1)
+ {
+ names.add(p.getProperty(key));
+ break;
+ }
+ }
+ }
+ }
+ // we have the factory class names in names; instantiate and enumerate
+ String c;
+ for (it = names.iterator(); it.hasNext(); )
+ {
+ c = (String) it.next();
+ try
+ {
+ SaslClientFactory f = (SaslClientFactory) Class.forName(c).newInstance();
+ if (f != null)
+ result.add(f);
+ } catch (ClassCastException ignored) { // ignore instantiation exceptions
+ } catch (ClassNotFoundException ignored) {
+ } catch (InstantiationException ignored) {
+ } catch (IllegalAccessException ignored) {
+ }
+ }
+
+ return result.elements();
+ }
+
+ /**
+ * Creates a {@link SaslServer} for the specified mechanism.
+ * + *This method uses the JCA Security Provider Framework, described in the + * "Java Cryptography Architecture API Specification & Reference", for + * locating and selecting a SaslServer implementation.
+ * + *First, it obtains an ordered list of {@link SaslServerFactory}
+ * instances from the registered security providers for the
+ * "SaslServerFactory" service and the specified mechanism. It
+ * then invokes createSaslServer() on each factory instance on
+ * the list until one produces a non-null {@link SaslServer} instance. It
+ * returns the non-null {@link SaslServer} instance, or null if
+ * the search fails to produce a non-null {@link SaslServer} instance.
A security provider for {@link SaslServerFactory} registers with the + * JCA Security Provider Framework keys of the form:
+ * + *+ * SaslServerFactory.mechanism_name + *+ * + *
and values that are class names of implementations of {@link + * SaslServerFactory}.
+ * + *For example, a provider that contains a factory class,
+ * com.wiz.sasl.digest.ServerFactory, that supports the
+ * "DIGEST-MD5" mechanism would register the following entry
+ * with the JCA:
+ * SaslServerFactory.DIGEST-MD5 com.wiz.sasl.digest.ServerFactory + *+ * + *
See the "Java Cryptography Architecture API Specification & + * Reference" for information about how to install and configure security + * service providers.
+ * + * @param mechanism the non-null mechanism name. It must be an + * IANA-registered name of a SASL mechanism. (e.g. "GSSAPI", "CRAM-MD5"). + * @param protocol the non-null string name of the protocol for which the + * authentication is being performed (e.g. "ldap"). + * @param serverName the non-null fully qualified host name of the server. + * @param props the possiblynull set of properties used to
+ * select the SASL mechanism and to configure the authentication exchange of
+ * the selected mechanism. For example, if props contains the {@link
+ * Sasl#POLICY_NOPLAINTEXT} property with the value "true", then
+ * the selected SASL mechanism must not be susceptible to simple plain
+ * passive attacks. In addition to the standard properties declared in this
+ * class, other, possibly mechanism-specific, properties can be included.
+ * Properties not relevant to the selected mechanism are ignored.
+ * @param cbh the possibly null callback handler to used by the
+ * SASL mechanisms to get further information from the application/library to
+ * complete the authentication. For example, a SASL mechanism might require
+ * the authentication ID, password and realm from the caller. The
+ * authentication ID is requested by using a
+ * {@link javax.security.auth.callback.NameCallback}. The password is
+ * requested by using a {@link javax.security.auth.callback.PasswordCallback}.
+ * The realm is requested by using a {@link RealmChoiceCallback} if there is
+ * a list of realms to choose from, and by using a {@link RealmCallback} if
+ * the realm must be entered.
+ * @return a possibly null {@link SaslServer} created using the
+ * parameters supplied. If null, the method cannot find a
+ * {@link SaslServerFactory} instance that will produce one.
+ * @throws SaslException if a {@link SaslServer} instance cannot be created
+ * because of an error.
+ */
+ public static SaslServer createSaslServer(String mechanism, String protocol,
+ String serverName,
+ Map props, CallbackHandler cbh)
+ throws SaslException
+ {
+ if (mechanism == null)
+ return null;
+ Provider[] providers = Security.getProviders();
+ if (providers == null || providers.length == 0)
+ return null;
+
+ SaslServer result = null;
+ SaslServerFactory factory = null;
+ String clazz = null, upper, alias = null;
+ int j;
+ Provider p;
+ for (j = 0; j < providers.length; j++)
+ {
+ p = providers[j];
+ if (p != null)
+ {
+ // try the name as is
+ clazz = p.getProperty(SERVER_FACTORY_SVC + mechanism);
+ if (clazz == null) // try all uppercase
+ {
+ upper = mechanism.toUpperCase();
+ clazz = p.getProperty(SERVER_FACTORY_SVC + upper);
+ if (clazz == null) // try if it's an alias
+ {
+ alias = p.getProperty(ALIAS + SERVER_FACTORY_SVC + mechanism);
+ if (alias == null) // try all-uppercase alias name
+ {
+ alias = p.getProperty(ALIAS + SERVER_FACTORY_SVC + upper);
+ if (alias == null) // spit the dummy
+ continue;
+ }
+ }
+ clazz = p.getProperty(SERVER_FACTORY_SVC + alias);
+ }
+ }
+ if (clazz == null)
+ continue;
+ else
+ clazz = clazz.trim();
+
+ try
+ {
+ result = null;
+ factory = (SaslServerFactory) Class.forName(clazz).newInstance();
+ result =
+ factory.createSaslServer(mechanism, protocol, serverName, props, cbh);
+ }
+ catch (ClassCastException ignored) // ignore instantiation exceptions
+ {
+ }
+ catch (ClassNotFoundException ignored)
+ {
+ }
+ catch (InstantiationException ignored)
+ {
+ }
+ catch (IllegalAccessException ignored)
+ {
+ }
+ if (result != null)
+ return result;
+ }
+ return null;
+ }
+
+ /**
+ * Gets an enumeration of known factories for producing a {@link SaslServer}
+ * instance. This method uses the same sources for locating factories as
+ * createSaslServer().
+ *
+ * @return a non-null {@link Enumeration} of known factories for producing a
+ * {@link SaslServer} instance.
+ * @see #createSaslServer(String,String,String,Map,CallbackHandler)
+ */
+ public static Enumeration getSaslServerFactories()
+ {
+ Vector result = new Vector();
+ HashSet names = new HashSet();
+ Provider[] providers = Security.getProviders();
+ Iterator it;
+ if (providers == null)
+ {
+ Provider p;
+ String key;
+ for (int i = 0; i < providers.length; i++)
+ {
+ p = providers[i];
+ for (it = p.keySet().iterator(); it.hasNext(); )
+ {
+ key = (String) it.next();
+ // add key's binding (a) it is a class of a server factory,
+ // and (b) the key does not include blanks
+ if (key.startsWith(SERVER_FACTORY_SVC) && key.indexOf(" ") == -1)
+ {
+ names.add(p.getProperty(key));
+ break;
+ }
+ }
+ }
+ }
+ // we have the factory class names in names; instantiate and enumerate
+ String c;
+ for (it = names.iterator(); it.hasNext(); )
+ {
+ c = (String) it.next();
+ try
+ {
+ SaslServerFactory f = (SaslServerFactory) Class.forName(c).newInstance();
+ if (f != null)
+ result.add(f);
+ }
+ catch (ClassCastException ignored) // ignore instantiation exceptions
+ {
+ }
+ catch (ClassNotFoundException ignored)
+ {
+ }
+ catch (InstantiationException ignored)
+ {
+ }
+ catch (IllegalAccessException ignored)
+ {
+ }
+ }
+
+ return result.elements();
+ }
+}
diff --git a/libjava/javax/security/sasl/SaslClient.java b/libjava/javax/security/sasl/SaslClient.java
new file mode 100644
index 00000000000..ca95ced2554
--- /dev/null
+++ b/libjava/javax/security/sasl/SaslClient.java
@@ -0,0 +1,231 @@
+/* SaslClient.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpathis free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpathis 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+/**
+ * Performs SASL authentication as a client.
+ * + *A protocol library such as one for LDAP gets an instance of this class in
+ * order to perform authentication defined by a specific SASL mechanism.
+ * Invoking methods on the SaslClient instance process challenges
+ * and create responses according to the SASL mechanism implemented by the
+ * SaslClient. As the authentication proceeds, the instance
+ * encapsulates the state of a SASL client's authentication exchange.
Here's an example of how an LDAP library might use a SaslClient.
+ * It first gets an instance of a SaslClient:
+ *SaslClient sc = + * Sasl.createSaslClient(mechanisms, authorizationID, protocol, + * serverName, props, callbackHandler); + *+ * + *
It can then proceed to use the client for authentication. For example, an + * LDAP library might use the client as follows:
+ *
+ * // Get initial response and send to server
+ *byte[] response = sc.hasInitialResponse()
+ * ? sc.evaluateChallenge(new byte[0]) : null;
+ *LdapResult res = ldap.sendBindRequest(dn, sc.getName(), response);
+ *while (!sc.isComplete()
+ * && ((res.status == SASL_BIND_IN_PROGRESS) || (res.status == SUCCESS))) {
+ * response = sc.evaluateChallenge( res.getBytes() );
+ * if (res.status == SUCCESS) {
+ * // we're done; don't expect to send another BIND
+ * if ( response != null ) {
+ * throw new SaslException(
+ * "Protocol error: attempting to send response after completion");
+ * }
+ * break;
+ * }
+ * res = ldap.sendBindRequest(dn, sc.getName(), response);
+ *}
+ *if (sc.isComplete() && (res.status == SUCCESS) ) {
+ * String qop = (String)sc.getNegotiatedProperty(Sasl.QOP);
+ * if ((qop != null)
+ * && (qop.equalsIgnoreCase("auth-int")
+ * || qop.equalsIgnoreCase("auth-conf"))) {
+ * // Use SaslClient.wrap() and SaslClient.unwrap() for future
+ * // communication with server
+ * ldap.in = new SecureInputStream(sc, ldap.in);
+ * ldap.out = new SecureOutputStream(sc, ldap.out);
+ * }
+ *}
+ *
+ *
+ * If the mechanism has an initial response, the library invokes + * {@link #evaluateChallenge(byte[])} with an empty challenge to get the initial + * response. Protocols such as IMAP4, which do not include an initial response + * with their first authentication command to the server, initiate the + * authentication without first calling {@link #hasInitialResponse()} or + * {@link #evaluateChallenge(byte[])}. When the server responds to the command, + * it sends an initial challenge. For a SASL mechanism in which the client sends + * data first, the server should have issued a challenge with no data. This will + * then result in a call (on the client) to {@link #evaluateChallenge(byte[])} + * with an empty challenge.
+ * + * @see Sasl + * @see SaslClientFactory + * @version $Revision: 1.1 $ + */ +public interface SaslClient +{ + + /** + * Returns the IANA-registered mechanism name of this SASL client. (e.g. + * "CRAM-MD5", "GSSAPI"). + * + * @return a non-null string representing the IANA-registered mechanism name. + */ + String getMechanismName(); + + /** + * Determines if this mechanism has an optional initial response. If + *true, caller should call {@link #evaluateChallenge(byte[])}
+ * with an empty array to get the initial response.
+ *
+ * @return true if this mechanism has an initial response.
+ */
+ boolean hasInitialResponse();
+
+ /**
+ * Evaluates the challenge data and generates a response. If a challenge is
+ * received from the server during the authentication process, this method is
+ * called to prepare an appropriate next response to submit to the server.
+ *
+ * @param challenge the non-null challenge sent from the server. The
+ * challenge array may have zero length.
+ * @return the possibly null reponse to send to the server. It
+ * is null if the challenge accompanied a "SUCCESS" status and
+ * the challenge only contains data for the client to update its state and no
+ * response needs to be sent to the server. The response is a zero-length
+ * byte array if the client is to send a response with no data.
+ * @throws SaslException if an error occurred while processing the challenge
+ * or generating a response.
+ */
+ byte[] evaluateChallenge(byte[] challenge) throws SaslException;
+
+ /**
+ * Determines if the authentication exchange has completed. This method may
+ * be called at any time, but typically, it will not be called until the
+ * caller has received indication from the server (in a protocol-specific
+ * manner) that the exchange has completed.
+ *
+ * @return true if the authentication exchange has completed;
+ * false otherwise.
+ */
+ boolean isComplete();
+
+ /**
+ * Unwraps a byte array received from the server. This method can be
+ * called only after the authentication exchange has completed (i.e., when
+ * {@link #isComplete()} returns true) and only if the
+ * authentication exchange has negotiated integrity and/or privacy as the
+ * quality of protection; otherwise, an {@link IllegalStateException} is
+ * thrown.
incoming is the contents of the SASL buffer as defined in
+ * RFC 2222 without the leading four octet field that represents the length.
+ * offset and len specify the portion of incoming
+ * to use.
incoming of the bytes
+ * to use.
+ * @param len the number of bytes from incoming to use.
+ * @return a non-null byte array containing the decoded bytes.
+ * @throws SaslException if incoming cannot be successfully
+ * unwrapped.
+ * @throws IllegalStateException if the authentication exchange has not
+ * completed, or if the negotiated quality of protection has neither
+ * integrity nor privacy.
+ */
+ byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException;
+
+ /**
+ * Wraps a byte array to be sent to the server. This method can be called
+ * only after the authentication exchange has completed (i.e., when
+ * {@link #isComplete()} returns true) and only if the
+ * authentication exchange has negotiated integrity and/or privacy as the
+ * quality of protection; otherwise, an {@link IllegalStateException} is
+ * thrown.
The result of this method will make up the contents of the SASL buffer
+ * as defined in RFC 2222 without the leading four octet field that
+ * represents the length. offset and len specify
+ * the portion of outgoing to use.
outgoing of the bytes
+ * to use.
+ * @param len the number of bytes from outgoing to use.
+ * @return a non-null byte array containing the encoded bytes.
+ * @throws SaslException if outgoing cannot be successfully
+ * wrapped.
+ * @throws IllegalStateException if the authentication exchange has not
+ * completed, or if the negotiated quality of protection has neither
+ * integrity nor privacy.
+ */
+ byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException;
+
+ /**
+ * Retrieves the negotiated property. This method can be called only after
+ * the authentication exchange has completed (i.e., when {@link #isComplete()}
+ * returns true); otherwise, an {@link IllegalStateException} is
+ * thrown.
+ *
+ * @param propName the non-null property name.
+ * @return the value of the negotiated property. If null, the
+ * property was not negotiated or is not applicable to this mechanism.
+ * @throws IllegalStateException if this authentication exchange has not
+ * completed.
+ */
+ Object getNegotiatedProperty(String propName) throws SaslException;
+
+ /**
+ * Disposes of any system resources or security-sensitive information the
+ * SaslClient might be using. Invoking this method invalidates
+ * the SaslClient instance. This method is idempotent.
+ *
+ * @throws SaslException if a problem was encountered while disposing of the
+ * resources.
+ */
+ void dispose() throws SaslException;
+}
diff --git a/libjava/javax/security/sasl/SaslClientFactory.java b/libjava/javax/security/sasl/SaslClientFactory.java
new file mode 100644
index 00000000000..b67c7a324f0
--- /dev/null
+++ b/libjava/javax/security/sasl/SaslClientFactory.java
@@ -0,0 +1,117 @@
+/* SaslClientFactory.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ * An interface for creating instances of {@link SaslClient}. A class that + * implements this interface must be thread-safe and handle multiple + * simultaneous requests. It must also have a public constructor that accepts + * no arguments.
+ * + *This interface is not normally accessed directly by a client, which will
+ * use the {@link Sasl} static methods to create a client instance instead.
+ * However, a particular environment may provide and install a new or different
+ * SaslClientFactory.
null or empty, the server
+ * derives an authorization ID from the client's authentication credentials.
+ * When the SASL authentication completes successfully, the specified entity
+ * is granted access.
+ * @param protocol the non-null string name of the protocol for which the
+ * authentication is being performed (e.g. "ldap").
+ * @param serverName the non-null fully qualified host name of the server to
+ * authenticate to.
+ * @param props the possibly null set of properties used to
+ * select the SASL mechanism and to configure the authentication exchange of
+ * the selected mechanism. See the {@link Sasl} class for a list of standard
+ * properties. Other, possibly mechanism-specific, properties can be included.
+ * Properties not relevant to the selected mechanism are ignored.
+ * @param cbh the possibly null callback handler to used by the
+ * SASL mechanisms to get further information from the application/library to
+ * complete the authentication. For example, a SASL mechanism might require
+ * the authentication ID, password and realm from the caller. The
+ * authentication ID is requested by using a
+ * {@link javax.security.auth.callback.NameCallback}. The password is
+ * requested by using a {@link javax.security.auth.callback.PasswordCallback}.
+ * The realm is requested by using a {@link RealmChoiceCallback} if there is
+ * a list of realms to choose from, and by using a {@link RealmCallback} if
+ * the realm must be entered.
+ * @return a possibly null {@link SaslClient} created using the
+ * parameters supplied. If null, this factory cannot produce a
+ * {@link SaslClient} using the parameters supplied.
+ * @throws SaslException if a {@link SaslClient} instance cannot be created
+ * because of an error.
+ */
+ SaslClient createSaslClient(String[] mechanisms, String authorizationID,
+ String protocol, String serverName, Map props,
+ CallbackHandler cbh)
+ throws SaslException;
+
+ /**
+ * Returns an array of names of mechanisms that match the specified mechanism
+ * selection policies.
+ *
+ * @param props the possibly null set of properties used to
+ * specify the security policy of the SASL mechanisms. For example, if props
+ * contains the {@link Sasl#POLICY_NOPLAINTEXT} property with the value
+ * "true", then the factory must not return any SASL mechanisms
+ * that are susceptible to simple plain passive attacks. See the {@link Sasl}
+ * class for a complete list of policy properties. Non-policy related
+ * properties, if present in props, are ignored.
+ * @return a non-null array containing IANA-registered SASL mechanism names.
+ */
+ String[] getMechanismNames(Map props);
+}
diff --git a/libjava/javax/security/sasl/SaslException.java b/libjava/javax/security/sasl/SaslException.java
new file mode 100644
index 00000000000..9ff091d6374
--- /dev/null
+++ b/libjava/javax/security/sasl/SaslException.java
@@ -0,0 +1,185 @@
+/* SaslException.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+
+/**
+ * This class represents an error that has occurred when using SASL.
+ *
+ * @version $Revision: 1.1 $
+ */
+public class SaslException extends IOException implements Serializable
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /**
+ * @serial The possibly null root cause exception.
+ */
+ private Throwable _exception = null;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Constructs a new instance of SaslException. The root
+ * exception and the detailed message are null.
+ */
+ public SaslException()
+ {
+ super();
+ }
+
+ /**
+ * Constructs a new instance of SaslException with a detailed
+ * message. The root exception is null.
+ *
+ * @param detail a possibly null string containing details of the exception.
+ * @see Throwable#getMessage()
+ */
+ public SaslException(String detail)
+ {
+ super(detail);
+ }
+
+ /**
+ * Constructs a new instance of SaslException with a detailed
+ * message and a root exception. For example, a SaslException
+ * might result from a problem with the callback handler, which might throw a
+ * {@link javax.security.auth.callback.UnsupportedCallbackException} if it
+ * does not support the requested callback, or throw an {@link IOException}
+ * if it had problems obtaining data for the callback. The
+ * SaslException's root exception would be then be the exception
+ * thrown by the callback handler.
+ *
+ * @param detail a possibly null string containing details of
+ * the exception.
+ * @param ex a possibly null root exception that caused this
+ * exception.
+ * @see Throwable#getMessage()
+ * @see #getCause()
+ */
+ public SaslException(String detail, Throwable ex)
+ {
+ super(detail);
+ _exception = ex;
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the cause of this throwable or null if the cause is
+ * nonexistent or unknown. The cause is the throwable that caused this
+ * exception to be thrown.
+ *
+ * @return the possibly null exception that caused this exception.
+ */
+ public Throwable getCause()
+ {
+ return _exception;
+ }
+
+ /**
+ * Prints this exception's stack trace to System.err. If this
+ * exception has a root exception; the stack trace of the root exception is
+ * also printed to System.err.
+ */
+ public void printStackTrace()
+ {
+ super.printStackTrace();
+ if (_exception != null)
+ _exception.printStackTrace();
+ }
+
+ /**
+ * Prints this exception's stack trace to a print stream. If this exception
+ * has a root exception; the stack trace of the root exception is also
+ * printed to the print stream.
+ *
+ * @param ps the non-null print stream to which to print.
+ */
+ public void printStackTrace(PrintStream ps)
+ {
+ super.printStackTrace(ps);
+ if (_exception != null)
+ _exception.printStackTrace(ps);
+ }
+
+ /**
+ * Prints this exception's stack trace to a print writer. If this exception
+ * has a root exception; the stack trace of the root exception is also
+ * printed to the print writer.
+ *
+ * @param pw the non-null print writer to use for output.
+ */
+ public void printStackTrace(PrintWriter pw)
+ {
+ super.printStackTrace(pw);
+ if (_exception != null)
+ _exception.printStackTrace(pw);
+ }
+
+ /**
+ * Returns the string representation of this exception. The string
+ * representation contains this exception's class name, its detailed
+ * messsage, and if it has a root exception, the string representation of the
+ * root exception. This string representation is meant for debugging and not
+ * meant to be interpreted programmatically.
+ *
+ * @return the non-null string representation of this exception.
+ * @see Throwable#getMessage()
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer(this.getClass().getName())
+ .append(": ").append(super.toString());
+ if (_exception != null)
+ sb.append("; caused by: ").append(_exception.toString());
+ return sb.toString();
+ }
+}
diff --git a/libjava/javax/security/sasl/SaslServer.java b/libjava/javax/security/sasl/SaslServer.java
new file mode 100644
index 00000000000..3f0d79d4412
--- /dev/null
+++ b/libjava/javax/security/sasl/SaslServer.java
@@ -0,0 +1,226 @@
+/* SasServer.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+/**
+ * Performs SASL authentication as a server.
+ * + *A server such as an LDAP server gets an instance of this class in order to
+ * perform authentication defined by a specific SASL mechanism. Invoking methods
+ * on the SaslServer instance generates challenges corresponding to
+ * the SASL mechanism implemented by the SaslServer instance. As
+ * the authentication proceeds, the instance encapsulates the state of a SASL
+ * server's authentication exchange.
Here's an example of how an LDAP server might use a SaslServer
+ * instance. It first gets an instance of a SaslServer for the SASL
+ * mechanism requested by the client:
+ *SaslServer ss = + * Sasl.createSaslServer(mechanism, "ldap", myFQDN, props, callbackHandler); + *+ * + *
It can then proceed to use the server for authentication. For example, + * suppose the LDAP server received an LDAP BIND request containing the name of + * the SASL mechanism and an (optional) initial response. It then might use the + * server as follows:
+ * + *
+ *while (!ss.isComplete()) {
+ * try {
+ * byte[] challenge = ss.evaluateResponse(response);
+ * if (ss.isComplete()) {
+ * status = ldap.sendBindResponse(mechanism, challenge, SUCCESS);
+ * } else {
+ * status = ldap.sendBindResponse(mechanism, challenge, SASL_BIND_IN_PROGRESS);
+ * response = ldap.readBindRequest();
+ * }
+ * } catch (SaslException x) {
+ * status = ldap.sendErrorResponse(x);
+ * break;
+ * }
+ *}
+ *if (ss.isComplete() && (status == SUCCESS)) {
+ * String qop = (String) sc.getNegotiatedProperty(Sasl.QOP);
+ * if (qop != null
+ * && (qop.equalsIgnoreCase("auth-int")
+ * || qop.equalsIgnoreCase("auth-conf"))) {
+ * // Use SaslServer.wrap() and SaslServer.unwrap() for future
+ * // communication with client
+ * ldap.in = new SecureInputStream(ss, ldap.in);
+ * ldap.out = new SecureOutputStream(ss, ldap.out);
+ * }
+ *}
+ *
+ *
+ * @see Sasl
+ * @see SaslServerFactory
+ * @version $Revision: 1.1 $
+ */
+public interface SaslServer
+{
+
+ /**
+ * Returns the IANA-registered mechanism name of this SASL server (e.g.
+ * "CRAM-MD5", "GSSAPI").
+ *
+ * @return a non-null string representing the IANA-registered mechanism name.
+ */
+ String getMechanismName();
+
+ /**
+ * Evaluates the response data and generates a challenge. If a response is
+ * received from the client during the authentication process, this method is
+ * called to prepare an appropriate next challenge to submit to the client.
+ * The challenge is null if the authentication has succeeded and
+ * no more challenge data is to be sent to the client. It is non-null if the
+ * authentication must be continued by sending a challenge to the client, or
+ * if the authentication has succeeded but challenge data needs to be
+ * processed by the client. {@link #isComplete()} should be called after each
+ * call to evaluateResponse(),to determine if any further
+ * response is needed from the client.
+ *
+ * @param response the non-null (but possibly empty) response sent by the
+ * client.
+ * @return the possibly null challenge to send to the client.
+ * It is null if the authentication has succeeded and there is
+ * no more challenge data to be sent to the client.
+ * @throws SaslException if an error occurred while processing the response
+ * or generating a challenge.
+ */
+ byte[] evaluateResponse(byte[] response) throws SaslException;
+
+ /**
+ * Determines if the authentication exchange has completed. This method is
+ * typically called after each invocation of {@link #evaluateResponse(byte[])}
+ * to determine whether the authentication has completed successfully or
+ * should be continued.
+ *
+ * @return true if the authentication exchange has completed;
+ * false otherwise.
+ */
+ boolean isComplete();
+
+ /**
+ * Reports the authorization ID in effect for the client of this session This
+ * method can only be called if {@link #isComplete()} returns true.
+ *
+ * @return the authorization ID of the client.
+ * @throws IllegalStateException if this authentication session has not
+ * completed.
+ */
+ String getAuthorizationID();
+
+ /**
+ * Unwraps a byte array received from the client. This method can be called
+ * only after the authentication exchange has completed (i.e., when
+ * {@link #isComplete()} returns true) and only if the
+ * authentication exchange has negotiated integrity and/or privacy as the
+ * quality of protection; otherwise, an {@link IllegalStateException} is
+ * thrown.
incoming is the contents of the SASL buffer as defined in
+ * RFC 2222 without the leading four octet field that represents the length.
+ * offset and len specify the portion of incoming
+ * to use.
incoming of the bytes
+ * to use.
+ * @param len the number of bytes from incoming to use.
+ * @return a non-null byte array containing the decoded bytes.
+ * @throws SaslException if incoming cannot be successfully
+ * unwrapped.
+ * @throws IllegalStateException if the authentication exchange has not
+ * completed, or if the negotiated quality of protection has neither
+ * integrity nor privacy.
+ */
+ byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException;
+
+ /**
+ * Wraps a byte array to be sent to the client. This method can be called
+ * only after the authentication exchange has completed (i.e., when
+ * {@link #isComplete()} returns true) and only if the
+ * authentication exchange has negotiated integrity and/or privacy as the
+ * quality of protection; otherwise, an {@link IllegalStateException} is
+ * thrown.
The result of this method will make up the contents of the SASL buffer
+ * as defined in RFC 2222 without the leading four octet field that
+ * represents the length. offset and len specify
+ * the portion of outgoing to use.
+ *
+ * @param outgoing a non-null byte array containing the bytes to encode.
+ * @param offset the starting position at outgoing of the bytes
+ * to use.
+ * @param len the number of bytes from outgoing to use.
+ * @return a non-null byte array containing the encoded bytes.
+ * @throws SaslException if outgoing cannot be successfully
+ * wrapped.
+ * @throws IllegalStateException if the authentication exchange has not
+ * completed, or if the negotiated quality of protection has neither
+ * integrity nor privacy.
+ */
+ byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException;
+
+ /**
+ * Retrieves the negotiated property. This method can be called only after
+ * the authentication exchange has completed (i.e., when
+ * {@link #isComplete()} returns true); otherwise, an
+ * {@link IllegalStateException} is thrown.
+ *
+ * @return the value of the negotiated property. If null, the
+ * property was not negotiated or is not applicable to this mechanism.
+ * @throws IllegalStateException if this authentication exchange has not
+ * completed.
+ */
+ Object getNegotiatedProperty(String propName) throws SaslException;
+
+ /**
+ * Disposes of any system resources or security-sensitive information the
+ * SaslServer might be using. Invoking this method invalidates
+ * the SaslServer instance. This method is idempotent.
+ *
+ * @throws SaslException if a problem was encountered while disposing of the
+ * resources.
+ */
+ void dispose() throws SaslException;
+}
diff --git a/libjava/javax/security/sasl/SaslServerFactory.java b/libjava/javax/security/sasl/SaslServerFactory.java
new file mode 100644
index 00000000000..b9387bbeed1
--- /dev/null
+++ b/libjava/javax/security/sasl/SaslServerFactory.java
@@ -0,0 +1,114 @@
+/* SaslServerFactory.java
+ Copyright (C) 2003, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307 USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.sasl;
+
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ *
An interface for creating instances of {@link SaslServer}. A class that + * implements this interface must be thread-safe and handle multiple + * simultaneous requests. It must also have a public constructor that accepts + * no arguments.
+ * + * This interface is not normally accessed directly by a server, which will use + * the {@link Sasl} static methods to create a {@link SaslServer} instance + * instead. However, a particular environment may provide and install a new or + * differentSaslServerFactory.
+ *
+ * @see SaslServer
+ * @see Sasl
+ * @version $Revision: 1.1 $
+ */
+public interface SaslServerFactory
+{
+
+ /**
+ * Creates a {@link SaslServer} instance using the parameters supplied. It
+ * returns null if no {@link SaslServer} instance can be created
+ * using the parameters supplied. Throws {@link SaslException} if it cannot
+ * create a {@link SaslServer} because of an error.
+ *
+ * @param mechanism the non-null IANA-registered name of a SASL mechanism
+ * (e.g. "GSSAPI", "CRAM-MD5").
+ * @param protocol the non-null string name of the protocol for which the
+ * authentication is being performed (e.g. "ldap").
+ * @param serverName the non-null fully qualified host name of the server to
+ * authenticate to.
+ * @param props the possibly null set of properties used to select the SASL
+ * mechanism and to configure the authentication exchange of the selected
+ * mechanism. See the {@link Sasl} class for a list of standard properties.
+ * Other, possibly mechanism-specific, properties can be included. Properties
+ * not relevant to the selected mechanism are ignored.
+ * @param cbh the possibly null callback handler to used by the SASL
+ * mechanisms to get further information from the application/library to
+ * complete the authentication. For example, a SASL mechanism might require
+ * the authentication ID, password and realm from the caller. The
+ * authentication ID is requested by using a
+ * {@link javax.security.auth.callback.NameCallback}. The password is
+ * requested by using a {@link javax.security.auth.callback.PasswordCallback}.
+ * The realm is requested by using a {@link RealmChoiceCallback} if there is
+ * a list of realms to choose from, and by using a {@link RealmCallback} if
+ * the realm must be entered.
+ * @return a possibly null {@link SaslServer} created using the parameters
+ * supplied. If null is returned, it means that this factory
+ * cannot produce a {@link SaslServer} using the parameters supplied.
+ * @throws SaslException if a SaslServer instance cannot be created because
+ * of an error.
+ */
+ SaslServer createSaslServer(String mechanism, String protocol,
+ String serverName, Map props, CallbackHandler cbh)
+ throws SaslException;
+
+ /**
+ * Returns an array of names of mechanisms that match the specified mechanism
+ * selection policies.
+ *
+ * @param props the possibly null set of properties used to
+ * specify the security policy of the SASL mechanisms. For example, if props
+ * contains the {@link Sasl#POLICY_NOPLAINTEXT} property with the value
+ * "true", then the factory must not return any SASL mechanisms
+ * that are susceptible to simple plain passive attacks. See the {@link Sasl}
+ * class for a complete list of policy properties. Non-policy related
+ * properties, if present in props, are ignored.
+ * @return a non-null array containing IANA-registered SASL mechanism names.
+ */
+ String[] getMechanismNames(Map props);
+}
diff --git a/libjava/org/ietf/jgss/ChannelBinding.java b/libjava/org/ietf/jgss/ChannelBinding.java
new file mode 100644
index 00000000000..9e966d54afb
--- /dev/null
+++ b/libjava/org/ietf/jgss/ChannelBinding.java
@@ -0,0 +1,215 @@
+/* ChannelBinding.java -- a channel binding in the GSS-API.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* The documentation comments of this class are derived from the text
+ of RFC 2853: Generic Security Service API Version 2: Java Bindings.
+ That document is covered under the following license notice:
+
+Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it
+or assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are
+included on all such copies and derivative works. However, this
+document itself may not be modified in any way, such as by removing
+the copyright notice or references to the Internet Society or other
+Internet organizations, except as needed for the purpose of developing
+Internet standards in which case the procedures for copyrights defined
+in the Internet Standards process must be followed, or as required to
+translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an
+"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
+WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
+
+
+package org.ietf.jgss;
+
+import java.net.InetAddress;
+import java.util.Arrays;
+
+/**
+ * The GSS-API accommodates the concept of caller-provided channel + * binding information. Channel bindings are used to strengthen the + * quality with which peer entity authentication is provided during + * context establishment. They enable the GSS-API callers to bind the + * establishment of the security context to relevant characteristics + * like addresses or to application specific data.
+ * + *The caller initiating the security context must determine the + * appropriate channel binding values to set in the {@link GSSContext} + * object. The acceptor must provide an identical binding in order to + * validate that received tokens possess correct channel-related + * characteristics.
+ * + *Use of channel bindings is optional in GSS-API. Since channel-binding + * information may be transmitted in context establishment tokens, + * applications should therefore not use confidential data as + * channel-binding components.
+ */ +public class ChannelBinding +{ + + // Fields. + // ------------------------------------------------------------------------- + + private final byte[] appData; + private final InetAddress initAddr; + private final InetAddress acceptAddr; + + // Constructor. + // ------------------------------------------------------------------------- + + /** + * Create a ChannelBinding object with user supplied address information + * and data.null values can be used for any fields which the
+ * application does not want to specify.
+ *
+ * @param initAddr The address of the context initiator. null
+ * value can be supplied to indicate that the application
+ * does not want to set this value.
+ * @param acceptAddr The address of the context acceptor. null
+ * value can be supplied to indicate that the application
+ * does not want to set this value.
+ * @param appData Application supplied data to be used as part of the
+ * channel bindings. null value can be
+ * supplied to indicate that the application does not
+ * want to set this value.
+ */
+ public ChannelBinding(InetAddress initAddr, InetAddress acceptAddr,
+ byte[] appData)
+ {
+ this.appData = (appData != null) ? (byte[]) appData.clone() : null;
+ this.initAddr = initAddr;
+ this.acceptAddr = acceptAddr;
+ }
+
+ /**
+ * Creates a ChannelBinding object without any addressing information.
+ *
+ * @param appData Application supplied data to be used as part of the
+ * channel bindings.
+ */
+ public ChannelBinding(byte[] appData)
+ {
+ this(null, null, appData);
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the initiator's address for this channel binding.
+ * null is returned if the address has not been set.
+ *
+ * @return The initiator's address, or null.
+ */
+ public InetAddress getInitiatorAddress()
+ {
+ return initAddr;
+ }
+
+ /**
+ * Returns the acceptor's address for this channel binding.
+ * null is returned if the address has not been set.
+ *
+ * @return The acceptor's address, or null.
+ */
+ public InetAddress getAcceptorAddress()
+ {
+ return acceptAddr;
+ }
+
+ /**
+ * Returns application data being used as part of the ChannelBinding.
+ * null is returned if no application data has been
+ * specified for the channel binding.
+ *
+ * @return The application data, or null.
+ */
+ public byte[] getApplicationData()
+ {
+ if (appData != null)
+ return (byte[]) appData.clone();
+ return null;
+ }
+
+ /**
+ * Returns true if two channel bindings match.
+ *
+ * @param obj Another channel binding to compare with.
+ * @return True if this channel binding equals the other.
+ */
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof ChannelBinding))
+ return false;
+ ChannelBinding cb = (ChannelBinding) obj;
+ boolean b1 = Arrays.equals(appData, cb.appData);
+ boolean b2 = (initAddr == null && cb.initAddr == null)
+ || (cb.initAddr != null && initAddr.equals(cb.initAddr));
+ boolean b3 = (acceptAddr == null && cb.acceptAddr == null)
+ || (cb.acceptAddr != null && acceptAddr.equals(cb.acceptAddr));
+ return b1 && b2 && b3;
+ }
+
+ /**
+ * Returns the hash code for this channel binding.
+ *
+ * @return The hash code.
+ */
+ public int hashCode()
+ {
+ int code = 0;
+ if (appData != null)
+ for (int i = 0; i < appData.length; i++)
+ code ^= appData[i] << ((8 * i) & 31);
+ if (initAddr != null)
+ code ^= initAddr.hashCode();
+ if (acceptAddr != null)
+ code ^= acceptAddr.hashCode();
+ return code;
+ }
+}
diff --git a/libjava/org/ietf/jgss/GSSContext.java b/libjava/org/ietf/jgss/GSSContext.java
new file mode 100644
index 00000000000..ab09c31c5c9
--- /dev/null
+++ b/libjava/org/ietf/jgss/GSSContext.java
@@ -0,0 +1,924 @@
+/* GSSContext.java -- The GSS context interface.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package org.ietf.jgss;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This interface encapsulates the GSS-API security context and provides + * the security services ({@link #wrap(byte[],int,int,org.ietf.jgss.MessageProp)}, + * {@link #unwrap(byte[],int,int,org.ietf.jgss.MessageProp)}, {@link + * #getMIC(byte[],int,int,org.ietf.jgss.MessageProp)}, {@link + * #verifyMIC(byte[],int,int,byte[],int,int,org.ietf.jgss.MessageProp)}) that + * are available over the context. Security contexts are established + * between peers using locally acquired credentials. Multiple contexts + * may exist simultaneously between a pair of peers, using the same or + * different set of credentials. GSS-API functions in a manner + * independent of the underlying transport protocol and depends on its + * calling application to transport its tokens between peers.
+ * + *Before the context establishment phase is initiated, the context + * initiator may request specific characteristics desired of the + * established context. These can be set using the set methods. After + * the context is established, the caller can check the actual + * characteristic and services offered by the context using the query + * methods.
+ * + *The context establishment phase begins with the first call to the + * init method by the context initiator. During this phase the + * {@link #initSecContext(byte[],int,int)} and {@link + * #acceptSecContext(byte[],int,int)} methods will produce GSS-API + * authentication tokens which the calling application needs to send to + * its peer. If an error occurs at any point, an exception will get + * thrown and the code will start executing in a catch block. If not, + * the normal flow of code continues and the application can make a call + * to the {@link #isEstablished()} method. If this method returns false it + * indicates that a token is needed from its peer in order to continue + * the context establishment phase. A return value of true signals that + * the local end of the context is established. This may still require + * that a token be sent to the peer, if one is produced by GSS-API. + * During the context establishment phase, the {@link #isProtReady()} + * method may be called to determine if the context can be used for the + * per-message operations. This allows applications to use per-message + * operations on contexts which aren't fully established.
+ * + *After the context has been established or the {@link #isProtReady()}
+ * method returns true, the query routines can be invoked to
+ * determine the actual characteristics and services of the established
+ * context. The application can also start using the per-message methods
+ * of {@link #wrap(byte[],int,int,org.ietf.jgss.MessageProp)} and
+ * {@link #getMIC(byte[],int,int,org.ietf.jgss.MessageProp)} to obtain
+ * cryptographic operations on application supplied data.
When the context is no longer needed, the application should call + * {@link dispose()} to release any system resources the context may be + * using.
+ * + *
+GSSManager mgr = GSSManager.getInstance();
+
+// start by creating the name for a service entity
+GSSName targetName = mgr.createName("service@host",
+ GSSName.NT_HOSTBASED_SERVICE);
+
+// create a context using default credentials for the above entity
+// and the implementation specific default mechanism
+GSSContext context = mgr.createContext(targetName,
+ null, // default mechanism
+ null, // default credentials
+ GSSContext.INDEFINITE_LIFETIME);
+
+// set desired context options - all others are false by default
+context.requestConf(true);
+context.requestMutualAuth(true);
+context.requestReplayDet(true);
+context.requestSequenceDet(true);
+
+// establish a context between peers - using byte arrays
+byte []inTok = new byte[0];
+
+try
+ {
+ do
+ {
+ byte[] outTok = context.initSecContext(inTok, 0,
+ inTok.length);
+
+ // send the token if present
+ if (outTok != null)
+ sendToken(outTok);
+
+ // check if we should expect more tokens
+ if (context.isEstablished())
+ break;
+
+ // another token expected from peer
+ inTok = readToken();
+
+ }
+ while (true);
+ }
+catch (GSSException e)
+ {
+ print("GSSAPI error: " + e.getMessage());
+ }
+
+// display context information
+print("Remaining lifetime in seconds = " + context.getLifetime());
+print("Context mechanism = " + context.getMech().toString());
+print("Initiator = " + context.getSrcName().toString());
+print("Acceptor = " + context.getTargName().toString());
+
+if (context.getConfState())
+ print("Confidentiality security service available");
+
+if (context.getIntegState())
+ print("Integrity security service available");
+
+// perform wrap on an application supplied message, appMsg,
+// using QOP = 0, and requesting privacy service
+byte[] appMsg ...
+MessageProp mProp = new MessageProp(0, true);
+byte[] tok = context.wrap(appMsg, 0, appMsg.length, mProp);
+
+if (mProp.getPrivacy())
+ print("Message protected with privacy.");
+
+sendToken(tok);
+
+
+// release the local-end of the context
+context.dispose();
+ *
+ */
+public interface GSSContext
+{
+
+ // Constants.
+ // -------------------------------------------------------------------------
+
+ /**
+ * A lifetime constant representing the default context lifetime.
+ */
+ int DEFAULT_LIFETIME = 0;
+
+ /**
+ * A lifetime constant representing indefinite context lifetime.
+ */
+ int INDEFINITE_LIFETIME = Integer.MAX_VALUE;
+
+ // Methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Called by the context initiator to start the context creation
+ * process. This is equivalent to the stream based method except that
+ * the token buffers are handled as byte arrays instead of using stream
+ * objects. This method may return an output token which the
+ * application will need to send to the peer for processing by the
+ * accept call. Typically, the application would do so by calling the
+ * {@link OutputStream#flush()} method on an OutputStream that
+ * encapsulates the connection between the two peers. The application
+ * can call {@link #isEstablished()} to determine if the context
+ * establishment phase is complete for this peer. A return value of
+ * false from {@link #isEstablished()} indicates that more
+ * tokens are expected to be supplied to the initSecContext() method. Note
+ * that it is possible that the initSecContext() method return a token for
+ * the peer, and {@link #isEstablished()} to return true also.
+ * This indicates that the token needs to be sent to the peer, but the local
+ * end of the context is now fully established.
Upon completion of the context establishment, the available context + * options may be queried through the get methods.
+ * + * @param inputBuf Token generated by the peer. This parameter is ignored + * on the first call. + * @param offset The offset within the inputBuf where the token + * begins. + * @param len The length of the token within the inputBuf + * (starting at the offset). + * @return The output token, if any. + * @throws GSSException If this operation fails. + */ + byte[] initSecContext(byte[] inputBuf, int offset, int len) + throws GSSException; + + /** + *Called by the context initiator to start the context creation
+ * process. This is equivalent to the byte array based method. This
+ * method may write an output token to the outStream, which the
+ * application will need to send to the peer for processing by the
+ * accept call. Typically, the application would do so by calling the
+ * {@link OutputStream#flush()} method on an OutputStream that encapsulates
+ * the connection between the two peers. The application can call {@link
+ * #isEstablished()} to determine if the context establishment phase is
+ * complete for this peer. A return value of false from
+ * isEstablished indicates that more tokens are expected to be supplied
+ * to the initSecContext() method. Note that it is possible that the
+ * initSecContext() method return a token for the peer, and {@link
+ * #isEstablished() return true also. This indicates that
+ * the token needs to be sent to the peer, but the local end of the context
+ * is now fully established.
The GSS-API authentication tokens contain a definitive start and end. + * This method will attempt to read one of these tokens per invocation, + * and may block on the stream if only part of the token is available.
+ * + *Upon completion of the context establishment, the available context + * options may be queried through the get methods.
+ * + * @param inStream Contains the token generated by the peer. This + * parameter is ignored on the first call. + * @param outStream Output stream where the output token will be written. + * During the final stage of context establishment, there + * may be no bytes written. + * @return The number of bytes written to outStream, or 0 if no + * token is written. + * @throws GSSException If this operation fails. + */ + int initSecContext(InputStream inStream, OutputStream outStream) + throws GSSException; + + /** + *Called by the context acceptor upon receiving a token from the peer. + * This call is equivalent to the stream based method except that the + * token buffers are handled as byte arrays instead of using stream + * objects.
+ * + *This method may return an output token which the application will + * need to send to the peer for further processing by the init call.
+ * + *null return value indicates that no token needs to be
+ * sent to the peer. The application can call {@link #isEstablished()}
+ * to determine if the context establishment phase is complete for this
+ * peer. A return value of false from {@link #isEstablished()}
+ * indicates that more tokens are expected to be supplied to this
+ * method.
Note that it is possible that acceptSecContext() return a token for
+ * the peer, and isEstablished() return true also. This
+ * indicates that the token needs to be sent to the peer, but the local
+ * end of the context is now fully established.
Upon completion of the context establishment, the available context + * options may be queried through the get methods.
+ * + * @param inTok Token generated by the peer. + * @param offset The offset within the inTok where the token begins. + * @param len The length of the token within the inTok (starting + * at the offset). + * @return The output token, if any. + * @throws GSSException If this operation fails. + */ + byte[] acceptSecContext(byte[] inTok, int offset, int len) + throws GSSException; + + /** + *Called by the context acceptor upon receiving a token from the peer.
+ * This call is equivalent to the byte array method. It may write an
+ * output token to the outStream, which the application will need to
+ * send to the peer for processing by its initSecContext method.
+ * Typically, the application would do so by calling the {@link
+ * OutputStream#flush()} method on an OutputStream that encapsulates the
+ * connection between the two peers. The application can call {@link
+ * #isEstablished()} to determine if the context establishment phase is
+ * complete for this peer. A return value of false from
+ * {@link #isEstablished()} indicates that more tokens are expected to be
+ * supplied to this method.
Note that it is possible that acceptSecContext() return a token for
+ * the peer, and isEstablished() return true also. This
+ * indicates that the token needs to be sent to the peer, but the local
+ * end of the context is now fully established.
The GSS-API authentication tokens contain a definitive start and end. + * This method will attempt to read one of these tokens per invocation, + * and may block on the stream if only part of the token is available.
+ * + *Upon completion of the context establishment, the available context + * options may be queried through the get methods.
+ * + * @param inStream Contains the token generated by the peer. + * @param outStream Output stream where the output token will be written. + * During the final stage of context establishment, there + * may be no bytes written. + * @return The number of bytes written, or 0 if no token is written. + * @throws GSSException If this operation fails. + */ + void acceptSecContext(InputStream inStream, OutputStream outStream) + throws GSSException; + + /** + * Used during context establishment to determine the state of the + * context. Returnstrue if this is a fully established
+ * context on the caller's side and no more tokens are needed from the
+ * peer. Should be called after a call to {@link
+ * #initSecContext(byte[],int,int)} or {@link
+ * #acceptSecContext(byte[],int,int)} when no {@link GSSException}
+ * is thrown.
+ *
+ * @return True of this context is fully established on this side.
+ */
+ boolean isEstablished();
+
+ /**
+ * Releases any system resources and cryptographic information stored in
+ * the context object. This will invalidate the context.
+ *
+ * @throws GSSException If this operation fails.
+ */
+ void dispose() throws GSSException;
+
+ /**
+ * Returns the maximum message size that, if presented to the + * {@link #wrap(byte[],int,int,org.ietf.jgss.MessageProp)} method with + * the same confReq and qop parameters, will result in an + * output token containing no more than the maxTokenSize bytes.
+ * + *This call is intended for use by applications that communicate over + * protocols that impose a maximum message size. It enables the + * application to fragment messages prior to applying protection.
+ * + *GSS-API implementations are recommended but not required to detect + * invalid QOP values when getWrapSizeLimit is called. This routine + * guarantees only a maximum message size, not the availability of + * specific QOP values for message protection.
+ * + *Successful completion of this call does not guarantee that wrap will + * be able to protect a message of the computed length, since this + * ability may depend on the availability of system resources at the + * time that wrap is called. However, if the implementation itself + * imposes an upper limit on the length of messages that may be + * processed by wrap, the implementation should not return a value that + * is greater than this length.
+ * + * @param qop Indicates the level of protection wrap will be asked + * to provide. + * @param confReq Indicates if wrap will be asked to provide privacy + * service. + * @param maxTokenSize The desired maximum size of the token emitted + * by {@link #wrap(byte[],int,int,org.ietf.jgss.MessageProp)}. + * @return The maximum wrapped output size. + * @throws GSSException If this operation fails. + */ + int getWrapSizeLimit(int qop, boolean confReq, int maxTokenSize) + throws GSSException; + + /** + *Applies per-message security services over the established security + * context. The method will return a token with a cryptographic MIC and + * may optionally encrypt the specified inBuf. This method is + * equivalent in functionality to its stream counterpart. The returned + * byte array will contain both the MIC and the message.
+ * + *The {@link MessageProp} object is instantiated by the application + * and used to specify a QOP value which selects cryptographic algorithms, + * and a privacy service to optionally encrypt the message. The underlying + * mechanism that is used in the call may not be able to provide the + * privacy service. It sets the actual privacy service that it does + * provide in this {@link MessageProp} object which the caller should then + * query upon return. If the mechanism is not able to provide the + * requested QOP, it throws a {@link GSSException} with the {@link + * GSSException#BAD_QOP} code.
+ * + *Since some application-level protocols may wish to use tokens emitted + * by wrap to provide "secure framing", implementations should support + * the wrapping of zero-length messages.
+ * + *The application will be responsible for sending the token to the + * peer.
+ * + * @param inBuf Application data to be protected. + * @param offset The offset within the inBuf where the data begins. + * @param len The length of the data within the inBuf (starting at + * the offset). + * @param msgProp Instance of {@link MessageProp} that is used by the + * application to set the desired QOP and privacy state. + * Set the desired QOP to 0 to request the default QOP. + * Upon return from this method, this object will contain + * the the actual privacy state that was applied to the + * message by the underlying mechanism. + * @return The wrapped data. + * @throws GSSException If this operation fails. + */ + byte[] wrap(byte[] inBuf, int offset, int len, MessageProp msgProp) + throws GSSException; + + /** + *Allows to apply per-message security services over the established + * security context. The method will produce a token with a + * cryptographic MIC and may optionally encrypt the message in inStream. + * The outStream will contain both the MIC and the message.
+ * + *The {@link MessageProp} object is instantiated by the application and + * used to specify a QOP value which selects cryptographic algorithms, and + * a privacy service to optionally encrypt the message. The underlying + * mechanism that is used in the call may not be able to provide the + * privacy service. It sets the actual privacy service that it does + * provide in this MessageProp object which the caller should then query + * upon return. If the mechanism is not able to provide the requested + * QOP, it throws a {@link GSSException} with the {@link + * GSSException#BAD_QOP} code.
+ * + *Since some application-level protocols may wish to use tokens emitted + * by wrap to provide "secure framing", implementations should support + * the wrapping of zero-length messages.
+ * + *The application will be responsible for sending the token to the + * peer.
+ * + * @param inStream Input stream containing the application data to be + * protected. + * @param outStream The output stream to write the protected message to. + * The application is responsible for sending this to the + * other peer for processing in its unwrap method. + * @param msgProp Instance of {@link MessageProp} that is used by the + * application to set the desired QOP and privacy state. + * Set the desired QOP to 0 to request the default QOP. + * Upon return from this method, this object will contain + * the the actual privacy state that was applied to the + * message by the underlying mechanism. + * @throws GSSException If this operation fails. + */ + void wrap(InputStream inStream, OutputStream outStream, MessageProp msgProp) + throws GSSException; + + /** + *Used by the peer application to process tokens generated with the + * wrap call. This call is equal in functionality to its stream + * counterpart. The method will return the message supplied in the peer + * application to the wrap call, verifying the embedded MIC.
+ * + *The {@link MessageProp} object is instantiated by the application and + * is used by the underlying mechanism to return information to the caller + * such as the QOP, whether confidentiality was applied to the message, and + * other supplementary message state information.
+ * + *Since some application-level protocols may wish to use tokens emitted + * by wrap to provide "secure framing", implementations should support + * the wrapping and unwrapping of zero-length messages.
+ * + * @param inBuf GSS-API wrap token received from peer. + * @param offset The offset within the inBuf where the token begins. + * @param len The length of the token within the inBuf (starting at + * the offset). + * @param msgProp Upon return from the method, this object will contain + * the applied QOP, the privacy state of the message, and + * supplementary information stating whether the token was + * a duplicate, old, out of sequence or arriving after a gap. + * @return The unwrapped token. + * @throws GSSException If this operation fails. + */ + byte[] unwrap(byte[] inBuf, int offset, int len, MessageProp msgProp) + throws GSSException; + + /** + *Used by the peer application to process tokens generated with the + * wrap call. This call is equal in functionality to its byte array + * counterpart. It will produce the message supplied in the peer + * application to the wrap call, verifying the embedded MIC.
+ * + *The {@link MessageProp} object is instantiated by the application + * and is used by the underlying mechanism to return information to the + * caller such as the QOP, whether confidentiality was applied to the + * message, and other supplementary message state information.
+ * + *Since some application-level protocols may wish to use tokens emitted + * by wrap to provide "secure framing", implementations should support + * the wrapping and unwrapping of zero-length messages.
+ * + * @param inStream Input stream containing the GSS-API wrap token + * received from the peer. + * @param outStream The output stream to write the application message to. + * @param msgProp Upon return from the method, this object will contain + * the applied QOP, the privacy state of the message, and + * supplementary information stating whether the token was + * a duplicate, old, out of sequence or arriving after a gap. + * @throws GSSException If this operation fails. + */ + void unwrap(InputStream inStream, OutputStream outStream, MessageProp msgProp) + throws GSSException; + + /** + *Returns a token containing a cryptographic MIC for the supplied + * message, for transfer to the peer application. Unlike wrap, which + * encapsulates the user message in the returned token, only the message + * MIC is returned in the output token. This method is identical in + * functionality to its stream counterpart.
+ * + *Note that privacy can only be applied through the wrap call.
+ * + *Since some application-level protocols may wish to use tokens emitted + * by getMIC to provide "secure framing", implementations should support + * derivation of MICs from zero-length messages.
+ * + * @param inMsg Message to generate MIC over. + * @param offset The offset within the inMsg where the token begins. + * @param len The length of the token within the inMsg (starting at + * the offset). + * @param msgProp Instance of MessageProp that is used by the + * application to set the desired QOP. Set the desired + * QOP to 0 in msgProp to request the default QOP. + * Alternatively pass innull for msgProp to
+ * request default QOP.
+ * @return The MIC.
+ * @throws GSSException If this operation fails.
+ */
+ byte[] getMIC(byte[] inMsg, int offset, int len, MessageProp msgProp)
+ throws GSSException;
+
+ /**
+ * Produces a token containing a cryptographic MIC for the supplied + * message, for transfer to the peer application. Unlike wrap, which + * encapsulates the user message in the returned token, only the message + * MIC is produced in the output token. This method is identical in + * functionality to its byte array counterpart.
+ * + *Note that privacy can only be applied through the wrap call.
+ * + *Since some application-level protocols may wish to use tokens emitted + * by getMIC to provide "secure framing", implementations should support + * derivation of MICs from zero-length messages.
+ * + * @param inStream Input stream containing the message to generate + * the MIC over. + * @param outStream Output stream to write the GSS-API output token to. + * @param msgProp Instance of MessageProp that is used by the + * application to set the desired QOP. Set the desired + * QOP to 0 in msgProp to request the default QOP. + * Alternatively pass innull for msgProp
+ * to request default QOP.
+ * @throws GSSException If this operation fails.
+ */
+ void getMIC(InputStream inStream, OutputStream outStream, MessageProp mgProp)
+ throws GSSException;
+
+ /**
+ * Verifies the cryptographic MIC, contained in the token parameter, + * over the supplied message. This method is equivalent in + * functionality to its stream counterpart.
+ * + *The MessageProp object is instantiated by the application and is used + * by the underlying mechanism to return information to the caller such + * as the QOP indicating the strength of protection that was applied to + * the message and other supplementary message state information.
+ * + *Since some application-level protocols may wish to use tokens emitted + * by getMIC to provide "secure framing", implementations should support + * the calculation and verification of MICs over zero-length messages.
+ * + * @param inTok Token generated by peer's getMIC method. + * @param tokOffset The offset within the inTok where the token begins. + * @param tokLen The length of the token within the inTok (starting at + * the offset). + * @param inMsg Application message to verify the cryptographic MIC + * over. + * @param msgOffset The offset within the inMsg where the message begins. + * @param msgLen The length of the message within the inMsg (starting + * at the offset). + * @param msgProp Upon return from the method, this object will contain + * the applied QOP and supplementary information + * stating whether the token was a duplicate, old, out + * of sequence or arriving after a gap. The + * confidentiality state will be set tofalse.
+ * @throws GSSException If this operation fails.
+ */
+ void verifyMIC(byte[] inTok, int tokOffset, int tokLen, byte[] inMsg,
+ int msgOffset, int msgLen, MessageProp msgProp)
+ throws GSSException;
+
+ /**
+ * Verifies the cryptographic MIC, contained in the token parameter, + * over the supplied message. This method is equivalent in + * functionality to its byte array counterpart.
+ * + *The MessageProp object is instantiated by the application and is used + * by the underlying mechanism to return information to the caller such + * as the QOP indicating the strength of protection that was applied to + * the message and other supplementary message state information.
+ * + *Since some application-level protocols may wish to use tokens emitted + * by getMIC to provide "secure framing", implementations should support + * the calculation and verification of MICs over zero-length messages.
+ * + * @param tokStream Input stream containing the token generated by peer's + * getMIC method. + * @param msgStream Input stream containing the application message to + * verify the cryptographic MIC over. + * @param msgProp Upon return from the method, this object will contain + * the applied QOP and supplementary information + * stating whether the token was a duplicate, old, out of + * sequence or arriving after a gap. The confidentiality + * state will be set tofalse.
+ * @throws GSSException If this operation fails.
+ */
+ void verifyMIC(InputStream tokStream, InputStream msgStream, MessageProp msgProp)
+ throws GSSException;
+
+ /**
+ * Provided to support the sharing of work between multiple processes. + * This routine will typically be used by the context-acceptor, in an + * application where a single process receives incoming connection + * requests and accepts security contexts over them, then passes the + * established context to one or more other processes for message + * exchange.
+ * + *This method deactivates the security context and creates an + * interprocess token which, when passed to the byte array constructor + * of the GSSContext interface in another process, will re-activate the + * context in the second process. Only a single instantiation of a + * given context may be active at any one time; a subsequent attempt by + * a context exporter to access the exported security context will fail.
+ * + *The implementation may constrain the set of processes by which the + * interprocess token may be imported, either as a function of local + * security policy, or as a result of implementation decisions. For + * example, some implementations may constrain contexts to be passed + * only between processes that run under the same account, or which are + * part of the same process group.
+ * + *The interprocess token may contain security-sensitive information + * (for example cryptographic keys). While mechanisms are encouraged to + * either avoid placing such sensitive information within interprocess + * tokens, or to encrypt the token before returning it to the + * application, in a typical GSS-API implementation this may not be + * possible. Thus the application must take care to protect the + * interprocess token, and ensure that any process to which the token is + * transferred is trustworthy.
+ * + * @return The exported context. + * @throws GSSException If this operation fails. + */ + byte[] export() throws GSSException; + + /** + *Sets the request state of the mutual authentication flag for the + * context. This method is only valid before the context creation + * process begins and only for the initiator.
+ * + * @param state Boolean representing if mutual authentication should + * be requested during context establishment. + * @throws GSSException If this operation fails. + */ + void requestMutualAuth(boolean state) throws GSSException; + + /** + *Sets the request state of the replay detection service for the + * context. This method is only valid before the context creation + * process begins and only for the initiator.
+ * + * @param state Boolean representing if replay detection is desired + * over the established context. + * @throws GSSException If this operation fails. + */ + void requestReplayDet(boolean state) throws GSSException; + + /** + *Sets the request state for the sequence checking service of the + * context. This method is only valid before the context creation + * process begins and only for the initiator.
+ * + * @param state Boolean representing if sequence detection is desired + * over the established context. + * @throws GSSException If this operation fails. + */ + void requestSequenceDet(boolean state) throws GSSException; + + /** + *Sets the request state for the credential delegation flag for the + * context. This method is only valid before the context creation + * process begins and only for the initiator.
+ * + * @param state Boolean representing if credential delegation is + * desired. + * @throws GSSException If this operation fails. + */ + void requestCredDeleg(boolean state) throws GSSException; + + /** + *Requests anonymous support over the context. This method is only + * valid before the context creation process begins and only for the + * initiator.
+ * + * @param state Boolean representing if anonymity support is requested. + * @throws GSSException If this operation fails. + */ + void requestAnonymity(boolean state) throws GSSException; + + /** + *Requests that confidentiality service be available over the context. + * This method is only valid before the context creation process begins + * and only for the initiator.
+ * + * @param state Boolean indicating if confidentiality services are to + * be requested for the context. + * @throws GSSException If this operation fails. + */ + void requestConf(boolean state) throws GSSException; + + /** + *Requests that integrity services be available over the context. This + * method is only valid before the context creation process begins and + * only for the initiator.
+ * + * @param state Boolean indicating if integrity services are to be + * requested for the context. + * @throws GSSException If this operation fails. + */ + void requestInteg(boolean state) throws GSSException; + + /** + *Sets the desired lifetime for the context in seconds. This method is + * only valid before the context creation process begins and only for + * the initiator. Use {@link #INDEFINITE_LIFETIME} and {@link + * #DEFAULT_LIFETIME} to request indefinite or default context lifetime.
+ * + * @param lifetime The desired context lifetime in seconds. + * @throws GSSException If this operation fails. + */ + void requestLifetime(int lifetime) throws GSSException; + + /** + *Sets the channel bindings to be used during context establishment. + * This method is only valid before the context creation process begins.
+ * + * @param cb Channel bindings to be used. + * @throws GSSException If this operation fails. + */ + void setChannelBinding(ChannelBinding cb) throws GSSException; + + /** + *Returns the state of the delegated credentials for the context. + * When issued before context establishment is completed or when the + * isProtReady method returns "false", it returns the desired state, + * otherwise it will indicate the actual state over the established + * context.
+ * + * @return The state of the delegated credentials for the context. + */ + boolean getCredDelegState(); + + /** + *Returns the state of the mutual authentication option for the + * context. When issued before context establishment completes or when + * the isProtReady method returns "false", it returns the desired state, + * otherwise it will indicate the actual state over the established + * context.
+ * + * @return The state of the mutual authentication option. + */ + boolean getMutualAuthState(); + + /** + *Returns the state of the replay detection option for the context. + * When issued before context establishment completes or when the + * isProtReady method returns "false", it returns the desired state, + * otherwise it will indicate the actual state over the established + * context.
+ * + * @return The state of the replay detection option. + */ + boolean getReplayDetState(); + + /** + *Returns the state of the sequence detection option for the context. + * When issued before context establishment completes or when the + * isProtReady method returns "false", it returns the desired state, + * otherwise it will indicate the actual state over the established + * context.
+ * + * @return The state of the sequence detection option. + */ + boolean getSequenceDetState(); + + /** + *Returns "true" if this is an anonymous context. When issued before + * context establishment completes or when the isProtReady method + * returns "false", it returns the desired state, otherwise it will + * indicate the actual state over the established context.
+ * + * @return True if this is an anonymous context. + */ + boolean getAnonymityState(); + + /** + *Returns "true" if the context is transferable to other processes + * through the use of the {@link #export()} method. This call is only + * valid on fully established contexts.
+ * + * @return True if the context is transferable. + * @throws GSSException If this operation fails. + */ + boolean isTransferable() throws GSSException; + + /** + *Returns "true" if the per message operations can be applied over + * the context. Some mechanisms may allow the usage of per-message + * operations before the context is fully established. This will also + * indicate that the get methods will return actual context state + * characteristics instead of the desired ones.
+ * + * @return True if the per message operations can be applied over + * the context. + */ + boolean isProtReady(); + + /** + *Returns the confidentiality service state over the context. When + * issued before context establishment completes or when the isProtReady + * method returns "false", it returns the desired state, otherwise it + * will indicate the actual state over the established context.
+ * + * @return True the confidentiality service state. + */ + boolean getConfState(); + + /** + *Returns the integrity service state over the context. When issued + * before context establishment completes or when the isProtReady method + * returns "false", it returns the desired state, otherwise it will + * indicate the actual state over the established context.
+ * + * @return The integrity service state. + */ + boolean getIntegState(); + + /** + *Returns the context lifetime in seconds. When issued before context + * establishment completes or when the isProtReady method returns + * "false", it returns the desired lifetime, otherwise it will indicate + * the remaining lifetime for the context.
+ * + * @return The lifetime. + */ + int getLifetime(); + + /** + *Returns the name of the context initiator. This call is valid only + * after the context is fully established or the isProtReady method + * returns "true". It is guaranteed to return an MN.
+ * + * @return The name of the context initiator. + * @throws GSSException If this operation fails. + */ + GSSName getSrcName() throws GSSException; + + /** + *Returns the name of the context target (acceptor). This call is + * valid only after the context is fully established or the isProtReady + * method returns "true". It is guaranteed to return an MN.
+ * + * @return The name of the context target. + * @throws GSSException If this operation fails. + */ + GSSName getTargName() throws GSSException; + + /** + *Returns the mechanism oid for this context. This method may be called + * before the context is fully established, but the mechanism returned + * may change on successive calls in negotiated mechanism case.
+ * + * @return The mechanism OID. + * @throws GSSException If this operation fails. + */ + Oid getMech() throws GSSException; + + /** + *Returns the delegated credential object on the acceptor's side. + * To check for availability of delegated credentials call + * {@link #getDelegCredState()}. This call is only valid on fully + * established contexts.
+ * + * @return The delegated credential object. + * @throws GSSException If this operation fails. + */ + GSSCredential getDelegCred() throws GSSException; + + /** + *Returns "true" if this is the initiator of the context. This call is + * only valid after the context creation process has started.
+ * + * @return True if this is the initiator. + * @throws GSSException If this operation fails. + */ + boolean isInitiator() throws GSSException; +} diff --git a/libjava/org/ietf/jgss/GSSCredential.java b/libjava/org/ietf/jgss/GSSCredential.java new file mode 100644 index 00000000000..318848ec90d --- /dev/null +++ b/libjava/org/ietf/jgss/GSSCredential.java @@ -0,0 +1,334 @@ +/* GSSCredential.java -- GSS credential interface. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* The documentation comments of this class are derived from the text + of RFC 2853: Generic Security Service API Version 2: Java Bindings. + That document is covered under the following license notice: + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it +or assist in its implementation may be prepared, copied, published and +distributed, in whole or in part, without restriction of any kind, +provided that the above copyright notice and this paragraph are +included on all such copies and derivative works. However, this +document itself may not be modified in any way, such as by removing +the copyright notice or references to the Internet Society or other +Internet organizations, except as needed for the purpose of developing +Internet standards in which case the procedures for copyrights defined +in the Internet Standards process must be followed, or as required to +translate it into languages other than English. + +The limited permissions granted above are perpetual and will not be +revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on an +"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN +WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ + + +package org.ietf.jgss; + +/** + *This interface encapsulates the GSS-API credentials for an entity. + * A credential contains all the necessary cryptographic information to + * enable the creation of a context on behalf of the entity that it + * represents. It may contain multiple, distinct, mechanism specific + * credential elements, each containing information for a specific + * security mechanism, but all referring to the same entity.
+ * + *A credential may be used to perform context initiation, acceptance, + * or both.
+ * + *GSS-API implementations must impose a local access-control policy on + * callers to prevent unauthorized callers from acquiring credentials to + * which they are not entitled. GSS-API credential creation is not + * intended to provide a "login to the network" function, as such a + * function would involve the creation of new credentials rather than + * merely acquiring a handle to existing credentials. Such functions, + * if required, should be defined in implementation-specific extensions + * to the API.
+ * + *If credential acquisition is time-consuming for a mechanism, the + * mechanism may choose to delay the actual acquisition until the + * credential is required (e.g. by {@link GSSContext}). Such mechanism- + * specific implementation decisions should be invisible to the calling + * application; thus the query methods immediately following the + * creation of a credential object must return valid credential data, + * and may therefore incur the overhead of a deferred credential + * acquisition.
+ * + *Applications will create a credential object passing the desired + * parameters. The application can then use the query methods to obtain + * specific information about the instantiated credential object + * (equivalent to the gss_inquire routines). When the credential is no + * longer needed, the application should call the dispose (equivalent to + * gss_release_cred) method to release any resources held by the + * credential object and to destroy any cryptographically sensitive + * information.
+ * + *Classes implementing this interface also implement the {@link Cloneable} + * interface. This indicates the the class will support the {@link + * Cloneable#clone()} method that will allow the creation of duplicate + * credentials. This is useful when called just before the {@link + * #add(org.ietf.jgss.GSSName,int,int,org.ietf.jgss.Oid,int)} call to retain + * a copy of the original credential.
+ * + *
+GSSManager mgr = GSSManager.getInstance();
+
+// start by creating a name object for the entity
+GSSName name = mgr.createName("userName", GSSName.NT_USER_NAME);
+
+// now acquire credentials for the entity
+GSSCredential cred = mgr.createCredential(name,
+ GSSCredential.ACCEPT_ONLY);
+
+// display credential information - name, remaining lifetime,
+// and the mechanisms it has been acquired over
+print(cred.getName().toString());
+print(cred.getRemainingLifetime());
+
+Oid [] mechs = cred.getMechs();
+if (mechs != null)
+ {
+ for (int i = 0; i < mechs.length; i++)
+ print(mechs[i].toString());
+ }
+
+// release system resources held by the credential
+cred.dispose();
+ *
+ */
+public interface GSSCredential extends Cloneable
+{
+
+ // Constants.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Credential usage flag requesting that it be able to be used for both
+ * context initiation and acceptance.
+ */
+ int INITIATE_AND_ACCEPT = 0;
+
+ /**
+ * Credential usage flag requesting that it be able to be used for
+ * context initiation only.
+ */
+ int INITIATE_ONLY = 1;
+
+ /**
+ * Credential usage flag requesting that it be able to be used for
+ * context acceptance only.
+ */
+ int ACCEPT_ONLY = 2;
+
+ /**
+ * A lifetime constant representing the default credential lifetime.
+ */
+ int DEFAULT_LIFETIME = 0;
+
+ /**
+ * A lifetime constant representing indefinite credential lifetime.
+ */
+ int INDEFINITE_LIFETIME = Integer.MAX_VALUE;
+
+ // Methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Releases any sensitive information that the GSSCredential object may
+ * be containing. Applications should call this method as soon as the
+ * credential is no longer needed to minimize the time any sensitive
+ * information is maintained.
+ *
+ * @throws GSSException If this operation fails.
+ */
+ void dispose() throws GSSException;
+
+ /**
+ * Retrieves the name of the entity that the credential asserts.
+ *
+ * @return The name.
+ * @throws GSSException If this operation fails.
+ */
+ GSSName getName() throws GSSException;
+
+ /**
+ * Retrieves a mechanism name of the entity that the credential asserts.
+ * Equivalent to calling {@link GSSName#canonicalize(org.ietf.jgss.Oid)}
+ * on the name returned by {@link #getName()}.
+ *
+ * @param mechOID The mechanism for which information should be returned.
+ * @return The name.
+ * @throws GSSException If this operation fails.
+ */
+ GSSName getName(Oid mechOID) throws GSSException;
+
+ /**
+ * Returns the remaining lifetime in seconds for a credential. The
+ * remaining lifetime is the minimum lifetime for any of the underlying
+ * credential mechanisms. A return value of {@link
+ * GSSCredential#INDEFINITE_LIFETIME} indicates that the credential does
+ * not expire. A return value of 0 indicates that the credential is
+ * already expired.
+ *
+ * @return The remaining lifetime.
+ * @throws GSSException If this operation fails.
+ */
+ int getRemainingLifetime() throws GSSException;
+
+ /**
+ * Returns the remaining lifetime is seconds for the credential to
+ * remain capable of initiating security contexts under the specified
+ * mechanism. A return value of {@link GSSCredential#INDEFINITE_LIFETIME}
+ * indicates that the credential does not expire for context initiation.
+ * A return value of 0 indicates that the credential is already expired.
+ *
+ * @param mech The mechanism for which information should be returned.
+ * @return The remaining lifetime.
+ * @throws GSSException If this operation fails.
+ */
+ int getRemainingInitLifetime(Oid mech) throws GSSException;
+
+ /**
+ * Returns the remaining lifetime is seconds for the credential to
+ * remain capable of accepting security contexts under the specified
+ * mechanism. A return value of {@link GSSCredential#INDEFINITE_LIFETIME}
+ * indicates that the credential does not expire for context acceptance.
+ * A return value of 0 indicates that the credential is already expired.
+ *
+ * @param mech The mechanism for which information should be returned.
+ * @return The remaining lifetime.
+ * @throws GSSException If this operation fails.
+ */
+ int getRemainingAcceptLifetime(Oid mech) throws GSSException;
+
+ /**
+ * Returns the credential usage flag. The return value will be one of
+ * {@link GSSCredential#INITIATE_ONLY}, {@link GSSCredential#ACCEPT_ONLY},
+ * or {@link GSSCredential#INITIATE_AND_ACCEPT}.
+ *
+ * @return The credential usage flag.
+ * @throws GSSException If this operation fails.
+ */
+ int getUsage() throws GSSException;
+
+ /**
+ * Returns the credential usage flag for the specified credential
+ * mechanism. The return value will be one of
+ * {@link GSSCredential#INITIATE_ONLY}, {@link GSSCredential#ACCEPT_ONLY},
+ * or {@link GSSCredential#INITIATE_AND_ACCEPT}.
+ *
+ * @param mechOID The mechanism for which information should be returned.
+ * @return The credential usage flag.
+ * @throws GSSException If this operation fails.
+ */
+ int getUsage(Oid mechOID) throws GSSException;
+
+ /**
+ * Returns an array of mechanisms supported by this credential.
+ *
+ * @return The supported mechanism.
+ * @throws GSSException If this operation fails.
+ */
+ Oid[] getMechs() throws GSSException;
+
+ /**
+ * Adds a mechanism specific credential-element to an existing + * credential. This method allows the construction of credentials one + * mechanism at a time.
+ * + *This routine is envisioned to be used mainly by context acceptors + * during the creation of acceptance credentials which are to be used + * with a variety of clients using different security mechanisms.
+ * + *This routine adds the new credential element "in-place". To add the
+ * element in a new credential, first call {@link Cloneable#clone()} to
+ * obtain a copy of this credential, then call its add()
+ * method.
null to
+ * specify the default principal.
+ * @param initLifetime The number of seconds that credentials should
+ * remain valid for initiating of security contexts.
+ * Use {@link #INDEFINITE_LIFETIME} to request that
+ * the credentials have the maximum permitted lifetime.
+ * Use {@link GSSCredential#DEFAULT_LIFETIME} to
+ * request the default credential lifetime.
+ * @param acceptLifetime The number of seconds that credentials should
+ * remain valid for accepting of security contexts.
+ * Use {@link GSSCredential#INDEFINITE_LIFETIME} to
+ * request that the credentials have the maximum
+ * permitted lifetime. Use {@link
+ * GSSCredential#DEFAULT_LIFETIME} to request
+ * the default credential lifetime.
+ * @param mech The mechanisms over which the credential is to be
+ * acquired.
+ * @param usage The intended usage for this credential object. The
+ * value of this parameter must be one of:
+ * {@link GSSCredential#ACCEPT_AND_INITIATE},
+ * {@link GSSCredential#ACCEPT_ONLY},
+ * {@link GSSCredential#INITIATE_ONLY}.
+ * @throws GSSException If this operation fails.
+ */
+ void add(GSSName aName, int initLifetime, int acceptLifetime,
+ Oid mech, int usage) throws GSSException;
+
+ /**
+ * Tests if this GSSCredential refers to the same entity as the supplied
+ * object. The two credentials must be acquired over the same
+ * mechanisms and must refer to the same principal. Returns true
+ * if the two GSSCredentials refer to the same entity; false
+ * otherwise. (Note that the Java language specification requires that two
+ * objects that are equal according to the {@link
+ * Object#equals(java.lang.Object)} method must return the same integer
+ * result when the {@link Object#hashCode()} method is called on them.)
+ *
+ * @param another Another GSSCredential object for comparison.
+ * @return True if this object equals the other.
+ */
+ boolean equals(Object another);
+}
diff --git a/libjava/org/ietf/jgss/GSSException.java b/libjava/org/ietf/jgss/GSSException.java
new file mode 100644
index 00000000000..72d91c0da16
--- /dev/null
+++ b/libjava/org/ietf/jgss/GSSException.java
@@ -0,0 +1,431 @@
+/* GSSException.java -- a general exception in GSS.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* The documentation comments of this class are derived from the text
+ of RFC 2853: Generic Security Service API Version 2: Java Bindings.
+ That document is covered under the following license notice:
+
+Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it
+or assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are
+included on all such copies and derivative works. However, this
+document itself may not be modified in any way, such as by removing
+the copyright notice or references to the Internet Society or other
+Internet organizations, except as needed for the purpose of developing
+Internet standards in which case the procedures for copyrights defined
+in the Internet Standards process must be followed, or as required to
+translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an
+"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
+WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
+
+
+package org.ietf.jgss;
+
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+
+/**
+ * This exception is thrown whenever a fatal GSS-API error occurs
+ * including mechanism specific errors. It may contain both, the major
+ * and minor, GSS-API status codes. The mechanism implementers are
+ * responsible for setting appropriate minor status codes when throwing
+ * this exception. Aside from delivering the numeric error code(s) to
+ * the caller, this class performs the mapping from their numeric values
+ * to textual representations. All Java GSS-API methods are declared
+ * throwing this exception.
+ */
+public class GSSException extends Exception
+{
+
+ // Constants and fields.
+ // -------------------------------------------------------------------------
+
+ // These values do not jive with the "Constant Field Values" in the J2SE
+ // 1.4.1, but do follow RFC 2853. I trust the IETF, but not Sun.
+
+ /**
+ * Channel bindings mismatch error.
+ */
+ public static final int BAD_BINDINGS = 4;
+
+ /**
+ * Unsupported mechanism requested error.
+ */
+ public static final int BAD_MECH = 1;
+
+ /**
+ * Invalid name provided error.
+ */
+ public static final int BAD_NAME = 2;
+
+ /**
+ * Name of unsupported type provided error.
+ */
+ public static final int BAD_NAMETYPE = 3;
+
+ /**
+ * Invalid status code error - this is the default status value.
+ */
+ public static final int BAD_STATUS = 5;
+
+ /**
+ * Token had invalid integrity check error.
+ */
+ public static final int BAD_MIC = 6;
+
+ /**
+ * Specified security context expired error.
+ */
+ public static final int CONTEXT_EXPIRED = 12;
+
+ /**
+ * Expired credentials detected error.
+ */
+ public static final int CREDENTIALS_EXPIRED = 11;
+
+ /**
+ * Defective credential error.
+ */
+ public static final int DEFECTIVE_CREDENTIAL = 10;
+
+ /**
+ * Defective token error.
+ */
+ public static final int DEFECTIVE_TOKEN = 9;
+
+ /**
+ * General failure, unspecified at GSS-API level.
+ */
+ public static final int FAILURE = 13;
+
+ /**
+ * Invalid security context error.
+ */
+ public static final int NO_CONTEXT = 8;
+
+ /**
+ * Invalid credentials error.
+ */
+ public static final int NO_CRED = 7;
+
+ /**
+ * Unsupported QOP value error.
+ */
+ public static final int BAD_QOP = 14;
+
+ /**
+ * Operation unauthorized error.
+ */
+ public static final int UNAUTHORIZED = 15;
+
+ /**
+ * Operation unavailable error.
+ */
+ public static final int UNAVAILABLE = 16;
+
+ /**
+ * Duplicate credential element requested error.
+ */
+ public static final int DUPLICATE_ELEMENT = 17;
+
+ /**
+ * Name contains multi-mechanism elements error.
+ */
+ public static final int NAME_NOT_MN = 18;
+
+ /**
+ * The token was a duplicate of an earlier token. This is a fatal error
+ * code that may occur during context establishment. It is not used to
+ * indicate supplementary status values. The MessageProp object is used
+ * for that purpose.
+ */
+ public static final int DUPLICATE_TOKEN = 20;
+
+ /**
+ * The token's validity period has expired. This is a fatal error code
+ * that may occur during context establishment. It is not used to
+ * indicate supplementary status values. The MessageProp object is used
+ * for that purpose.
+ */
+ public static final int OLD_TOKEN = 19;
+
+ /**
+ * A later token has already been processed. This is a fatal error code
+ * that may occur during context establishment. It is not used to
+ * indicate supplementary status values. The MessageProp object is used
+ * for that purpose.
+ */
+ public static final int UNSEQ_TOKEN = 21;
+
+ /**
+ * An expected per-message token was not received. This is a fatal
+ * error code that may occur during context establishment. It is not
+ * used to indicate supplementary status values. The MessageProp object
+ * is used for that purpose.
+ */
+ public static final int GAP_TOKEN = 22;
+
+ private final int major;
+ private int minor;
+ private String minorString;
+
+ private ResourceBundle messages;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a new GSS exception with the given major code.
+ *
+ * @param major The major GSS error code.
+ */
+ public GSSException(int major)
+ {
+ this(major, 0, null);
+ }
+
+ /**
+ * Create a new GSS exception with the given major and minor codes, and a
+ * minor explanation string.
+ *
+ * @param major The major GSS error code.
+ * @param minor The minor application-specific error code.
+ * @param minorString An explanation of the minor error code.
+ */
+ public GSSException(int major, int minor, String minorString)
+ {
+ this.major = major;
+ this.minor = minor;
+ this.minorString = minorString;
+ try
+ {
+ messages = PropertyResourceBundle.getBundle("org/ietf/jgss/MessagesBundle");
+ }
+ catch (Exception e)
+ {
+ messages = null;
+ }
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the major code representing the GSS error code that caused
+ * this exception to be thrown.
+ *
+ * @return The major error code.
+ */
+ public int getMajor()
+ {
+ return major;
+ }
+
+ /**
+ * Returns the mechanism error code that caused this exception. The
+ * minor code is set by the underlying mechanism. Value of 0 indicates
+ * that mechanism error code is not set.
+ *
+ * @return The minor error code, or 0 if not set.
+ */
+ public int getMinor()
+ {
+ return minor;
+ }
+
+ /**
+ * Returns a string explaining the GSS major error code causing this
+ * exception to be thrown.
+ *
+ * @return The major error string.
+ */
+ public String getMajorString()
+ {
+ switch (major)
+ {
+ case BAD_MECH:
+ return getMsg("GSSException.BAD_MECH",
+ "An unsupported mechanism was requested.");
+ case BAD_NAME:
+ return getMsg("GSSException.BAD_NAME",
+ "An invalid name was supplied.");
+ case BAD_NAMETYPE:
+ return getMsg("GSSException.BAD_NAMETYPE",
+ "A supplied name was of an unsupported type.");
+ case BAD_BINDINGS:
+ return getMsg("GSSException.BAD_BINDINGS",
+ "Incorrect channel bindings were supplied.");
+ case BAD_STATUS:
+ return getMsg("GSSException.BAD_STATUS",
+ "An invalid status code was supplied.");
+ case BAD_MIC:
+ return getMsg("GSSException.BAD_MIC",
+ "A token had an invalid MIC.");
+ case NO_CRED:
+ return getMsg("GSSException.NO_CRED",
+ "No credentials were supplied, or the credentials were "+
+ "unavailable or inaccessible.");
+ case NO_CONTEXT:
+ return getMsg("GSSException.NO_CONTEXT",
+ "Invalid context has been supplied.");
+ case DEFECTIVE_TOKEN:
+ return getMsg("GSSException.DEFECTIVE_TOKEN",
+ "A supplied token was invalid.");
+ case DEFECTIVE_CREDENTIAL:
+ return getMsg("GSSException.DEFECTIVE_CREDENTIAL",
+ "A supplied credential was invalid.");
+ case CREDENTIALS_EXPIRED:
+ return getMsg("GSSException.CREDENTIALS_EXPIRED",
+ "The referenced credentials have expired.");
+ case CONTEXT_EXPIRED:
+ return getMsg("GSSException.CONTEXT_EXPIRED",
+ "The context has expired.");
+ case FAILURE:
+ return getMsg("GSSException.FAILURE",
+ "Miscellaneous failure.");
+ case BAD_QOP:
+ return getMsg("GSSException.BAD_QOP",
+ "The quality-of-protection requested could not be provided.");
+ case UNAUTHORIZED:
+ return getMsg("GSSException.UNAUTHORIZED",
+ "The operation is forbidden by local security policy.");
+ case UNAVAILABLE:
+ return getMsg("GSSException.UNAVAILABLE",
+ "The operation or option is unavailable.");
+ case DUPLICATE_ELEMENT:
+ return getMsg("GSSException.DUPLICATE_ELEMENT",
+ "The requested credential element already exists.");
+ case NAME_NOT_MN:
+ return getMsg("GSSException.NAME_NOT_MN",
+ "The provided name was not a mechanism name.");
+ case OLD_TOKEN:
+ return getMsg("GSSException.OLD_TOKEN",
+ "The token's validity period has expired.");
+ case DUPLICATE_TOKEN:
+ return getMsg("GSSException.DUPLICATE_TOKEN",
+ "The token was a duplicate of an earlier version.");
+ case UNSEQ_TOKEN:
+ return getMsg("GSSException.UNSEQ_TOKEN",
+ "A later token has already been processed.");
+ case GAP_TOKEN:
+ return getMsg("GSSException.GAP_TOKEN",
+ "An expected per-message token was not received.");
+ default: return "Unknown or invalid error code.";
+ }
+ }
+
+ /**
+ * Returns a string explaining the mechanism specific error code.
+ * null will be returned when no mechanism error code has
+ * been set.
+ *
+ * @return The minor error string, or null.
+ */
+ public String getMinorString()
+ {
+ return minorString;
+ }
+
+ /**
+ * Used internally by the GSS-API implementation and the underlying
+ * mechanisms to set the minor code and its textual representation.
+ *
+ * @param minorCode The mechanism specific error code.
+ * @param message A textual explanation of the mechanism error code.
+ */
+ public void setMinor(int minorCode, String message)
+ {
+ this.minor = minorCode;
+ this.minorString = message;
+ }
+
+ /**
+ * Returns a textual representation of both the major and minor status
+ * codes.
+ *
+ * @return The textual representation.
+ */
+ public String toString()
+ {
+ return GSSException.class.getName() + ": " + getMessage();
+ }
+
+ /**
+ * Returns a detailed message of this exception. Overrides {@link
+ * Throwable#getMessage()}. It is customary in Java to use this method to
+ * obtain exception information.
+ *
+ * @return The detail message.
+ */
+ public String getMessage()
+ {
+ if (minor == 0)
+ return getMajorString();
+ else
+ return getMajorString() + " (" + minorString + ")";
+ }
+
+ // Own methods.
+ // -------------------------------------------------------------------------
+
+ private String getMsg(String key, String defaultText)
+ {
+ if (messages != null)
+ {
+ try
+ {
+ return messages.getString(key);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ return defaultText;
+ }
+}
diff --git a/libjava/org/ietf/jgss/GSSManager.java b/libjava/org/ietf/jgss/GSSManager.java
new file mode 100644
index 00000000000..26fdd14b67d
--- /dev/null
+++ b/libjava/org/ietf/jgss/GSSManager.java
@@ -0,0 +1,501 @@
+/* GSSManager.java -- manager class for the GSS-API.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* The documentation comments of this class are derived from the text
+ of RFC 2853: Generic Security Service API Version 2: Java Bindings.
+ That document is covered under the following license notice:
+
+Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it
+or assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are
+included on all such copies and derivative works. However, this
+document itself may not be modified in any way, such as by removing
+the copyright notice or references to the Internet Society or other
+Internet organizations, except as needed for the purpose of developing
+Internet standards in which case the procedures for copyrights defined
+in the Internet Standards process must be followed, or as required to
+translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an
+"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
+WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
+
+
+package org.ietf.jgss;
+
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * The GSSManager class is an abstract class that serves as a factory + * for three GSS interfaces: {@link GSSName}, {@link GSSCredential}, and + * {@link GSSContext}. It also provides methods for applications to determine + * what mechanisms are available from the GSS implementation and what + * nametypes these mechanisms support. An instance of the default GSSManager + * subclass may be obtained through the static method {@link #getInstance()}, + * but applications are free to instantiate other subclasses of GSSManager.
+ * + *All but one method in this class are declared abstract. This means + * that subclasses have to provide the complete implementation for those + * methods. The only exception to this is the static method {@link + * #getInstance()} which will have platform specific code to return an + * instance of the default subclass.
+ * + *Platform providers of GSS are required not to add any constructors to + * this class, private, public, or protected. This will ensure that all + * subclasses invoke only the default constructor provided to the base + * class by the compiler.
+ * + *A subclass extending the GSSManager abstract class may be implemented + * as a modular provider based layer that utilizes some well known + * service provider specification. The GSSManager API provides the + * application with methods to set provider preferences on such an + * implementation. These methods also allow the implementation to throw + * a well-defined exception in case provider based configuration is not + * supported. Applications that expect to be portable should be aware of + * this and recover cleanly by catching the exception.
+ * + *It is envisioned that there will be three most common ways in which + * providers will be used:
+ * + *The GSSManager class has two methods that enable these modes of + * usage: {@link #addProviderAtFront(java.security.Provider,org.ietf.jgss.Oid)} + * and {@link #addProviderAtEnd(java.security.Provider,org.ietf.jgss.Oid)}. + * These methods have the effect of creating an ordered list of + * (provider, oid) pairs where each pair indicates a preference + * of provider for a given oid.
+ * + *The use of these methods does not require any knowledge of whatever + * service provider specification the GSSManager subclass follows. It is + * hoped that these methods will serve the needs of most applications. + * Additional methods may be added to an extended GSSManager that could + * be part of a service provider specification that is standardized + * later.
+ * + *
+GSSManager mgr = GSSManager.getInstance();
+
+// What mechs are available to us?
+Oid[] supportedMechs = mgr.getMechs();
+
+// Set a preference for the provider to be used when support is needed
+// for the mechanisms "1.2.840.113554.1.2.2" and "1.3.6.1.5.5.1.1".
+
+Oid krb = new Oid("1.2.840.113554.1.2.2");
+Oid spkm1 = new Oid("1.3.6.1.5.5.1.1");
+
+Provider p = (Provider) (new com.foo.security.Provider());
+
+mgr.addProviderAtFront(p, krb);
+mgr.addProviderAtFront(p, spkm1);
+
+// What name types does this spkm implementation support?
+Oid[] nameTypes = mgr.getNamesForMech(spkm1);
+
+ */
+public abstract class GSSManager
+{
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ public GSSManager()
+ {
+ }
+
+ // Class method.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the default GSSManager implementation.
+ *
+ * @return The default GSSManager implementation.
+ */
+ public static synchronized GSSManager getInstance()
+ {
+ String impl = Security.getProperty("org.ietf.jgss.GSSManager");
+ if (impl == null)
+ impl = "gnu.crypto.gssapi.GSSManagerImpl";
+ try
+ {
+ ClassLoader loader = GSSManager.class.getClassLoader();
+ if (loader == null)
+ loader = ClassLoader.getSystemClassLoader();
+ Class c = loader.loadClass(impl);
+ return (GSSManager) c.newInstance();
+ }
+ catch (Exception x)
+ {
+ throw new RuntimeException(x.toString());
+ }
+ }
+
+ // Abstract methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * This method is used to indicate to the GSSManager that the + * application would like a particular provider to be used if no other + * provider can be found that supports the given mechanism. When a value + * of null is used instead of an Oid for the mechanism, the GSSManager + * must use the indicated provider for any mechanism.
+ * + *Calling this method repeatedly preserves the older settings but + * raises them above newer ones in preference thus forming an ordered + * list of providers and Oid pairs that grows at the bottom. Thus the + * older provider settings will be utilized first before this one is.
+ * + *If there are any previously existing preferences that conflict with + * the preference being set here, then the GSSManager should ignore this + * request.
+ * + *If the GSSManager implementation does not support an SPI with a + * pluggable provider architecture it should throw a GSSException with + * the status code {@link GSSException#UNAVAILABLE} to indicate that the + * operation is unavailable.
+ * + * @param p The provider instance that should be used whenever + * support is needed for mech. + * @param mech The mechanism for which the provider is being set. + * @throws GSSException If this service is unavailable. + */ + public abstract void addProviderAtEnd(Provider p, Oid mech) + throws GSSException; + + /** + *This method is used to indicate to the GSSManager that the + * application would like a particular provider to be used ahead of all + * others when support is desired for the given mechanism. When a value + * of null is used instead of an Oid for the mechanism, the GSSManager + * must use the indicated provider ahead of all others no matter what + * the mechanism is. Only when the indicated provider does not support + * the needed mechanism should the GSSManager move on to a different + * provider.
+ * + *Calling this method repeatedly preserves the older settings but + * lowers them in preference thus forming an ordered list of provider + * and Oid pairs that grows at the top.
+ * + *Calling addProviderAtFront with a null Oid will remove all previous + * preferences that were set for this provider in the GSSManager + * instance. Calling addProviderAtFront with a non-null Oid will remove + * any previous preference that was set using this mechanism and this + * provider together.
+ * + *If the GSSManager implementation does not support an SPI with a + * pluggable provider architecture it should throw a GSSException with + * the status code {@link GSSException#UNAVAILABLE} to indicate that the + * operation is unavailable.
+ * + * @param p The provider instance that should be used whenever + * support is needed for mech. + * @param mech The mechanism for which the provider is being set. + * @throws GSSException If this service is unavailable. + */ + public abstract void addProviderAtFront(Provider p, Oid mech) + throws GSSException; + + /** + * Factory method for creating a previously exported context. The + * context properties will be determined from the input token and can't + * be modified through the set methods. + * + * @param interProcessToken The token previously emitted from the + * export method. + * @return The context. + * @throws GSSException If this operation fails. + */ + public abstract GSSContext createContext(byte[] interProcessToken) + throws GSSException; + + /** + * Factory method for creating a context on the acceptor' side. The + * context's properties will be determined from the input token supplied + * to the accept method. + * + * @param myCred Credentials for the acceptor. Usenull to
+ * act as a default acceptor principal.
+ * @return The context.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSContext createContext(GSSCredential myCred)
+ throws GSSException;
+
+ /**
+ * Factory method for creating a context on the initiator's side.
+ * Context flags may be modified through the mutator methods prior to
+ * calling {@link
+ * GSSContext#initSecContext(java.io.InputStream,java.io.OutputStream)}.
+ *
+ * @param peer Name of the target peer.
+ * @param mech Oid of the desired mechanism. Use null
+ * to request default mechanism.
+ * @param myCred Credentials of the initiator. Use null
+ * default initiator principal.
+ * @param lifetime The request lifetime, in seconds, for the context.
+ * Use {@link GSSContext#INDEFINITE_LIFETIME} and
+ * {@link GSSContext#DEFAULT_LIFETIME} to request
+ * indefinite or default context lifetime.
+ * @return The context.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSContext createContext(GSSName peer, Oid mech,
+ GSSCredential myCred, int lifetime)
+ throws GSSException;
+
+ /**
+ * Factory method for acquiring default credentials. This will cause
+ * the GSS-API to use system specific defaults for the set of
+ * mechanisms, name, and a DEFAULT lifetime.
+ *
+ * @param usage The intended usage for this credential object. The
+ * value of this parameter must be one of:
+ * {@link GSSCredential#ACCEPT_AND_INITIATE},
+ * {@link GSSCredential#ACCEPT_ONLY},
+ * {@link GSSCredential#INITIATE_ONLY}.
+ * @return The credential.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSCredential createCredential(int usage) throws GSSException;
+
+ /**
+ * Factory method for acquiring a single mechanism credential.
+ *
+ * @param aName Name of the principal for whom this credential is to
+ * be acquired. Use null to specify the
+ * default principal.
+ * @param lifetime The number of seconds that credentials should remain
+ * valid. Use {@link GSSCredential#INDEFINITE_LIFETIME}
+ * to request that the credentials have the maximum
+ * permitted lifetime. Use {@link
+ * GSSCredential#DEFAULT_LIFETIME} to request default
+ * credential lifetime.
+ * @param mech The oid of the desired mechanism. Use null
+ * to request the default mechanism(s).
+ * @param usage The intended usage for this credential object. The
+ * value of this parameter must be one of:
+ * {@link GSSCredential#ACCEPT_AND_INITIATE},
+ * {@link GSSCredential#ACCEPT_ONLY},
+ * {@link GSSCredential#INITIATE_ONLY}.
+ * @return The credential.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSCredential createCredential(GSSName aName, int lifetime,
+ Oid mech, int usage)
+ throws GSSException;
+
+ /**
+ * Factory method for acquiring credentials over a set of mechanisms.
+ * Acquires credentials for each of the mechanisms specified in the
+ * array called mechs. To determine the list of mechanisms' for which
+ * the acquisition of credentials succeeded, the caller should use the
+ * {@link GSSCredential#getMechs()} method.
+ *
+ * @param aName Name of the principal for whom this credential is to
+ * be acquired. Use null to specify the
+ * default principal.
+ * @param lifetime The number of seconds that credentials should remain
+ * valid. Use {@link GSSCredential#INDEFINITE_LIFETIME}
+ * to request that the credentials have the maximum
+ * permitted lifetime. Use {@link
+ * GSSCredential#DEFAULT_LIFETIME} to request default
+ * credential lifetime.
+ * @param mechs The array of mechanisms over which the credential is
+ * to be acquired. Use null for requesting
+ * a system specific default set of mechanisms.
+ * @param usage The intended usage for this credential object. The
+ * value of this parameter must be one of:
+ * {@link GSSCredential#ACCEPT_AND_INITIATE},
+ * {@link GSSCredential#ACCEPT_ONLY},
+ * {@link GSSCredential#INITIATE_ONLY}.
+ * @return The credential.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSCredential createCredential(GSSName aName, int lifetime,
+ Oid[] mechs, int usage)
+ throws GSSException;
+
+ /**
+ * Factory method to convert a contiguous byte array containing a name
+ * from the specified namespace to a {@link GSSName} object. In general,
+ * the {@link GSSName} object created will not be an MN; two examples that
+ * are exceptions to this are when the namespace type parameter indicates
+ * {@link GSSName#NT_EXPORT_NAME} or when the GSS-API implementation is not
+ * multi-mechanism.
+ *
+ * @param name The byte array containing the name to create.
+ * @param nameType The Oid specifying the namespace of the name supplied
+ * in the byte array. Note that nameType serves to
+ * describe and qualify the interpretation of the input
+ * name byte array, it does not necessarily imply a type
+ * for the output GSSName implementation. "null" value
+ * can be used to specify that a mechanism specific
+ * default syntax should be assumed by each mechanism
+ * that examines the byte array.
+ * @return The name.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSName createName(byte[] name, Oid nameType)
+ throws GSSException;
+
+ /**
+ * Factory method to convert a contiguous byte array containing a name
+ * from the specified namespace to a GSSName object that is an MN. In
+ * other words, this method is a utility that does the equivalent of two
+ * steps: {@link #createName(byte[],org.ietf.jgss.Oid)} and then also
+ * {@link GSSName#canonicalize(org.ietf.jgss.Oid)}.
+ *
+ * @param name The byte array representing the name to create.
+ * @param nameType The Oid specifying the namespace of the name supplied
+ * in the byte array. Note that nameType serves to
+ * describe and qualify the interpretation of the input
+ * name byte array, it does not necessarily imply a type
+ * for the output GSSName implementation. "null" value
+ * can be used to specify that a mechanism specific
+ * default syntax should be assumed by each mechanism
+ * that examines the byte array.
+ * @param mech Oid specifying the mechanism for which this name
+ * should be created.
+ * @return The name.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSName createName(byte[] name, Oid nameType, Oid mech)
+ throws GSSException;
+
+ /**
+ * Factory method to convert a contiguous string name from the specified
+ * namespace to a {@link GSSName} object. In general, the {@link GSSName}
+ * object created will not be an MN; two examples that are exceptions to
+ * this are when the namespace type parameter indicates {@link
+ * GSSName#NT_EXPORT_NAME} or when the GSS-API implementation is not
+ * multi-mechanism.
+ *
+ * @param nameStr The string representing a printable form of the name
+ * to create.
+ * @param nameType The Oid specifying the namespace of the printable name
+ * supplied. Note that nameType serves to describe and
+ * qualify the interpretation of the input nameStr, it
+ * does not necessarily imply a type for the output
+ * GSSName implementation. "null" value can be used to
+ * specify that a mechanism specific default printable
+ * syntax should be assumed by each mechanism that
+ * examines nameStr.
+ * @return The name.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSName createName(String nameStr, Oid nameType)
+ throws GSSException;
+
+ /**
+ * Factory method to convert a contiguous string name from the specified
+ * namespace to an GSSName object that is a mechanism name (MN). In
+ * other words, this method is a utility that does the equivalent of two
+ * steps: the {@link #createName(java.lang.String,org.ietf.jgss.Oid)}
+ * and then also {@link GSSName#canonicalize(org.ietf.jgss.Oid)}.
+ *
+ * @param nameStr The string representing a printable form of the name
+ * to create.
+ * @param nameType The Oid specifying the namespace of the printable name
+ * supplied. Note that nameType serves to describe and
+ * qualify the interpretation of the input nameStr, it
+ * does not necessarily imply a type for the output
+ * GSSName implementation. "null" value can be used to
+ * specify that a mechanism specific default printable
+ * syntax should be assumed when the mechanism examines
+ * nameStr.
+ * @param mech Oid specifying the mechanism for which this name
+ * should be created.
+ * @return The name.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract GSSName createName(String nameStr, Oid nameType, Oid mech)
+ throws GSSException;
+
+ /**
+ * Returns an array of {@link Oid} objects indicating mechanisms available
+ * to GSS-API callers. A null value is returned when no
+ * mechanism are available (an example of this would be when mechanism are
+ * dynamically configured, and currently no mechanisms are installed).
+ *
+ * @return The array of available mechanisms, or null.
+ */
+ public abstract Oid[] getMechs();
+
+ /**
+ * Returns an array of {@link Oid} objects corresponding to the mechanisms
+ * that support the specific name type. null is returned when
+ * no mechanisms are found to support the specified name type.
+ *
+ * @param name The Oid object for the name type.
+ * @return The array of mechanisms, or null.
+ */
+ public abstract Oid[] getMechsForName(Oid name);
+
+ /**
+ * Returns name type Oid's supported by the specified mechanism.
+ *
+ * @param mechanism The Oid object for the mechanism to query.
+ * @return The name type Oid's supported by the mechanism.
+ * @throws GSSException If this operation fails.
+ */
+ public abstract Oid[] getNamesForMech(Oid mechanism) throws GSSException;
+}
diff --git a/libjava/org/ietf/jgss/GSSName.java b/libjava/org/ietf/jgss/GSSName.java
new file mode 100644
index 00000000000..fd158a90016
--- /dev/null
+++ b/libjava/org/ietf/jgss/GSSName.java
@@ -0,0 +1,269 @@
+/* GSSName.java -- a name interface for GSS.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* The documentation comments of this class are derived from the text
+ of RFC 2853: Generic Security Service API Version 2: Java Bindings.
+ That document is covered under the following license notice:
+
+Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it
+or assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are
+included on all such copies and derivative works. However, this
+document itself may not be modified in any way, such as by removing
+the copyright notice or references to the Internet Society or other
+Internet organizations, except as needed for the purpose of developing
+Internet standards in which case the procedures for copyrights defined
+in the Internet Standards process must be followed, or as required to
+translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an
+"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
+WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
+
+
+package org.ietf.jgss;
+
+/**
+ * This interface encapsulates a single GSS-API principal entity. + * Different name formats and their definitions are identified with + * universal Object Identifiers (Oids). The format of the names can be + * derived based on the unique oid of its namespace type.
+ * + *
+GSSManager mgr = GSSManager.getInstance();
+
+// create a host based service name
+GSSName name = mgr.createName("service@host",
+ GSSName.NT_HOSTBASED_SERVICE);
+
+Oid krb5 = new Oid("1.2.840.113554.1.2.2");
+
+GSSName mechName = name.canonicalize(krb5);
+
+// the above two steps are equivalent to the following
+GSSName mechName = mgr.createName("service@host",
+ GSSName.NT_HOSTBASED_SERVICE, krb5);
+
+// perform name comparison
+if (name.equals(mechName))
+ print("Names are equal.");
+
+// obtain textual representation of name and its printable
+// name type
+print(mechName.toString() +
+ mechName.getStringNameType().toString());
+
+// export and re-import the name
+byte [] exportName = mechName.export();
+
+// create a new name object from the exported buffer
+GSSName newName = mgr.createName(exportName,
+ GSSName.NT_EXPORT_NAME);
+
+ */
+public interface GSSName
+{
+
+ // Constants.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Name type for representing an anonymous entity. It represents the
+ * following value: { 1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name) }.
Name type used to indicate an exported name produced by the export
+ * method. It represents the following value: { 1(iso), 3(org), 6(dod),
+ * 1(internet), 5(security), 6(nametypes), 4(gss-api-exported-name)
+ * }.
Oid indicating a host-based service name form. It is used to + * represent services associated with host computers. This name form is + * constructed using two elements, "service" and "hostname", as follows:
+ * + *service@hostname
+ *
+ * Values for the "service" element are registered with the IANA. It
+ * represents the following value: { 1(iso), 3(org), 6(dod),
+ * 1(internet), 5(security), 6(nametypes), 2(gss-host-based-services)
+ * }.
Name type to indicate a numeric user identifier corresponding to a
+ * user on a local system. (e.g. Uid). It represents the following
+ * value: { iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2) }.
Name type to indicate a string of digits representing the numeric
+ * user identifier of a user on a local system. It represents the
+ * following value: { iso(1) member-body(2) United States(840)
+ * mit(113554) infosys(1) gssapi(2) generic(1) string_uid_name(3)
+ * }.
Name type to indicate a named user on a local system. It represents
+ * the following value: { iso(1) member-body(2) United States(840)
+ * mit(113554) infosys(1) gssapi(2) generic(1) user_name(1) }.
false.
+ *
+ * @param another GSSName object to compare with.
+ * @return True if this name equals the other, and if neither name
+ * represents an anonymous entity.
+ * @throws GSSException If the names cannot be compared.
+ */
+ boolean equals(GSSName another) throws GSSException;
+
+ /**
+ * A variation of the {@link #equals(org.ietf.jgss.GSSName)} method that
+ * is provided to override the {@link Object#equals(java.lang.Object)}
+ * method that the implementing class will inherit. The behavior is
+ * exactly the same as that in the other equals method except that no
+ * {@link GSSException} is thrown; instead, false will be
+ * returned in the situation where an error occurs. (Note that the Java
+ * language specification requires that two objects that are equal
+ * according to the {@link Object#equals(java.lang.Object)} method must
+ * return the same integer when the {@link hashCode()} method is called
+ * on them.
+ *
+ * @param another GSSName object to compare with.
+ * @return True if this name equals the other, if neither name
+ * represents an anonymous entity, or if an error occurs.
+ */
+ boolean equals(Object another);
+
+ /**
+ * Creates a mechanism name (MN) from an arbitrary internal name. This
+ * is equivalent to using the factory methods {@link
+ * GSSManager#createName(java.lang.String,org.ietf.jgss.Oid,org.ietf.jgss.Oid)}
+ * or {@link
+ * GSSManager#createName(byte[],org.ietf.jgss.Oid,org.ietf.jgss.Oid)}.
+ *
+ * @param mech The oid for the mechanism for which the canonical form
+ * of the name is requested.
+ * @return The mechanism name.
+ * @throws GSSException If this operation fails.
+ */
+ GSSName canonicalize(Oid mech) throws GSSException;
+
+ /**
+ * Returns a canonical contiguous byte representation of a mechanism
+ * name (MN), suitable for direct, byte by byte comparison by
+ * authorization functions. If the name is not an MN, implementations
+ * may throw a {@link GSSException} with the {@link GSSException#NAME_NOT_MN}
+ * status code. If an implementation chooses not to throw an exception,
+ * it should use some system specific default mechanism to canonicalize
+ * the name and then export it. The format of the header of the output
+ * buffer is specified in RFC 2743.
+ *
+ * @return The exported name.
+ * @throws GSSException If the name is not an MN and the implementation
+ * throws an exception for this case.
+ */
+ byte[] export() throws GSSException;
+
+ /**
+ * Returns a textual representation of the GSSName object. To retrieve
+ * the printed name format, which determines the syntax of the returned
+ * string, the {@link #getStringNameType()} method can be used.
+ *
+ * @return The textual representation of the GSSName object.
+ */
+ String toString();
+
+ /**
+ * Returns the oid representing the type of name returned through the
+ * {@link #toString()} method. Using this oid, the syntax of the printable
+ * name can be determined.
+ *
+ * @return The name type.
+ * @throws GSSException If this operation fails.
+ */
+ Oid getStringNameType() throws GSSException;
+
+ /**
+ * Tests if this name object represents an anonymous entity. Returns
+ * true if this is an anonymous name.
+ *
+ * @return True if this name represents an anonymous entity.
+ */
+ boolean isAnonymous();
+
+ /**
+ * Tests if this name object contains only one mechanism element and is
+ * thus a mechanism name as defined by RFC 2743.
+ *
+ * @return True if this name is a mechanism name.
+ */
+ boolean isMN();
+}
diff --git a/libjava/org/ietf/jgss/MessageProp.java b/libjava/org/ietf/jgss/MessageProp.java
new file mode 100644
index 00000000000..a3fd22e55a8
--- /dev/null
+++ b/libjava/org/ietf/jgss/MessageProp.java
@@ -0,0 +1,273 @@
+/* MessageProp.java -- GSS-API message property.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* The documentation comments of this class are derived from the text
+ of RFC 2853: Generic Security Service API Version 2: Java Bindings.
+ That document is covered under the following license notice:
+
+Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it
+or assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are
+included on all such copies and derivative works. However, this
+document itself may not be modified in any way, such as by removing
+the copyright notice or references to the Internet Society or other
+Internet organizations, except as needed for the purpose of developing
+Internet standards in which case the procedures for copyrights defined
+in the Internet Standards process must be followed, or as required to
+translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an
+"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
+WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
+
+
+package org.ietf.jgss;
+
+/**
+ * This is a utility class used within the per-message {@link + * GSSContext} methods to convey per-message properties.
+ * + *When used with the GSSContext interface's {@link + * GSSContext#wrap(byte[],int,int,org.ietf.jgss.MessageProp)} and {@link + * GSSContext#getMIC(byte[],int,int,org.ietf.jgss.MessageProp)} methods, an + * instance of this class is used to indicate the desired QOP and to + * request if confidentiality services are to be applied to caller + * supplied data (wrap only). To request default QOP, the value of 0 + * should be used for QOP.
+ * + *When used with the {@link + * GSSContext#unwrap(byte[],int,int,org.ietf.jgss.MessageProp)} and {@link + * GSSContext#verifyMIC(byte[],int,int,byte[],int,int,org.ietf.jgss.MessageProp)} + * methods of the GSSContext interface, an instance of this class will be + * used to indicate the applied QOP and confidentiality services over the + * supplied message. In the case of verifyMIC, the confidentiality state + * will always be "false". Upon return from these methods, this object will + * also contain any supplementary status values applicable to the processed + * token. The supplementary status values can indicate old tokens, out + * of sequence tokens, gap tokens or duplicate tokens.
+ */ +public class MessageProp +{ + + // Fields. + // ------------------------------------------------------------------------- + + private int qopVal; + private boolean privState; + private boolean duplicate; + private boolean old; + private boolean unseq; + private boolean gap; + private int minorStatus; + private String minorString; + + // Constructors. + // ------------------------------------------------------------------------- + + /** + *Constructor which sets QOP to 0 indicating that the default QOP is + * requested.
+ * + * @param privState The desired privacy state. "true" for privacy and + * "false" for integrity only. + */ + public MessageProp(boolean privState) + { + this(0, privState); + } + + /** + *Constructor which sets the values for the qop and privacy state.
+ * + * @param qop The desired QOP. Use 0 to request a default QOP. + * @param privState The desired privacy state. "true" for privacy and + * "false" for integrity only. + */ + public MessageProp(int qop, boolean privState) + { + this.qopVal = qop; + this.privState = privState; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + /** + * Retrieves the QOP value. + * + * @return The QOP value. + */ + public int getQOP() + { + return qopVal; + } + + /** + * Retrieves the privacy state. + * + * @return The privacy state. + */ + public boolean getPrivacy() + { + return privState; + } + + /** + * Retrieves the minor status that the underlying mechanism might have + * set. + * + * @return The minor status. + */ + public int getMinorStatus() + { + return minorStatus; + } + + /** + * Returns a string explaining the mechanism specific error code. + *null will be returned when no mechanism error code has
+ * been set.
+ *
+ * @return The minor status string.
+ */
+ public String getMinorString()
+ {
+ return minorString;
+ }
+
+ /**
+ * Sets the QOP value.
+ *
+ * @param qopVal The QOP value to be set. Use 0 to request a default
+ * QOP value.
+ */
+ public void setQOP(int qopVal)
+ {
+ this.qopVal = qopVal;
+ }
+
+ /**
+ * Sets the privacy state.
+ *
+ * @param privState The privacy state to set.
+ */
+ public void setPrivacy(boolean privState)
+ {
+ this.privState = privState;
+ }
+
+ /**
+ * Returns "true" if this is a duplicate of an earlier token.
+ *
+ * @return True if this is a duplicate of an earlier token.
+ */
+ public boolean isDuplicateToken()
+ {
+ return duplicate;
+ }
+
+ /**
+ * Returns "true" if the token's validity period has expired.
+ *
+ * @return True if the token's validity period has expired.
+ */
+ public boolean isOldToken()
+ {
+ return old;
+ }
+
+ /**
+ * Returns "true" if a later token has already been processed.
+ *
+ * @return True if a later token has already been processed.
+ */
+ public boolean isUnseqToken()
+ {
+ return unseq;
+ }
+
+ /**
+ * Returns "true" if an expected per-message token was not received.
+ *
+ * @return True if an expected per-message token was not received.
+ */
+ public boolean isGapToken()
+ {
+ return gap;
+ }
+
+ /**
+ * This method sets the state for the supplementary information flags
+ * and the minor status in MessageProp. It is not used by the
+ * application but by the GSS implementation to return this information
+ * to the caller of a per-message context method.
+ *
+ * @param duplicate True if the token was a duplicate of an earlier
+ * token, false otherwise.
+ * @param old True if the token's validity period has expired,
+ * false otherwise.
+ * @param unseq True if a later token has already been processed,
+ * false otherwise.
+ * @param gap True if one or more predecessor tokens have not yet
+ * been successfully processed, false otherwise.
+ * @param minorStatus The integer minor status code that the underlying
+ * mechanism wants to set.
+ * @param minorString The textual representation of the minorStatus
+ * value.
+ */
+ public void setSupplementaryStates(boolean duplicate, boolean old,
+ boolean unseq, boolean gap,
+ int minorStatus, String minorString)
+ {
+ this.duplicate = duplicate;
+ this.old = old;
+ this.unseq = unseq;
+ this.gap = gap;
+ this.minorStatus = minorStatus;
+ this.minorString = minorString;
+ }
+}
diff --git a/libjava/org/ietf/jgss/MessagesBundle.properties b/libjava/org/ietf/jgss/MessagesBundle.properties
new file mode 100644
index 00000000000..af8247cbff8
--- /dev/null
+++ b/libjava/org/ietf/jgss/MessagesBundle.properties
@@ -0,0 +1,60 @@
+# MessagesBundle.properties -- English GSS messages.
+# Copyright (C) 2004 Free Software Foundation, Inc.
+#
+# This file is a part of GNU Classpath.
+#
+# GNU Classpath is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# GNU Classpath 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 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Classpath; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+#
+# Linking this library statically or dynamically with other modules is
+# making a combined work based on this library. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give
+# you permission to link this library with independent modules to
+# produce an executable, regardless of the license terms of these
+# independent modules, and to copy and distribute the resulting
+# executable under terms of your choice, provided that you also meet,
+# for each linked independent module, the terms and conditions of the
+# license of that module. An independent module is a module which is
+# not derived from or based on this library. If you modify this
+# library, you may extend this exception to your version of the
+# library, but you are not obligated to do so. If you do not wish to
+# do so, delete this exception statement from your version.
+
+GSSException.BAD_MECH=An unsupported mechanism was requested.
+GSSException.BAD_NAME=An invalid name was supplied.
+GSSException.BAD_NAMETYPE=A supplied name was of an unsupported type.
+GSSException.BAD_BINDINGS=Incorrect channel bindings were supplied.
+GSSException.BAD_STATUS=An invalid status code was supplied.
+GSSException.BAD_MIC=A token had an invalid MIC.
+GSSException.NO_CRED=No credentials were supplied, or the credentials were unavailable or inaccessible.
+GSSException.NO_CONTEXT=Invalid context has been supplied.
+GSSException.DEFECTIVE_TOKEN=A supplied token was invalid.
+GSSException.DEFECTIVE_CREDENTIAL=A supplied credential was invalid.
+GSSException.CREDENTIALS_EXPIRED=The referenced credentials have expired.
+GSSException.CONTEXT_EXPIRED=The context has expired.
+GSSException.FAILURE=Miscellaneous failure.
+GSSException.BAD_QOP=The quality-of-protection requested could not be provided.
+GSSException.UNAUTHORIZED=The operation is forbidden by local security policy.
+GSSException.UNAVAILABLE=The operation or option is unavailable.
+GSSException.DUPLICATE_ELEMENT=The requested credential element already exists.
+GSSException.NAME_NOT_MN=The provided name was not a mechanism name.
+GSSException.OLD_TOKEN=The token\'s validity period has expired.
+GSSException.DUPLICATE_TOKEN=The token was a duplicate of an earlier version.
+GSSException.UNSEQ_TOKEN=A later token has already been processed.
+GSSException.GAP_TOKEN=An expected per-message token was not received.
+
diff --git a/libjava/org/ietf/jgss/Oid.java b/libjava/org/ietf/jgss/Oid.java
new file mode 100644
index 00000000000..a7c67a7103a
--- /dev/null
+++ b/libjava/org/ietf/jgss/Oid.java
@@ -0,0 +1,385 @@
+/* Oid.java -- Object identifier class.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* The documentation comments of this class are derived from the text
+ of RFC 2853: Generic Security Service API Version 2: Java Bindings.
+ That document is covered under the following license notice:
+
+Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it
+or assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are
+included on all such copies and derivative works. However, this
+document itself may not be modified in any way, such as by removing
+the copyright notice or references to the Internet Society or other
+Internet organizations, except as needed for the purpose of developing
+Internet standards in which case the procedures for copyrights defined
+in the Internet Standards process must be followed, or as required to
+translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an
+"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
+WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
+
+
+package org.ietf.jgss;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.math.BigInteger;
+
+import java.util.Arrays;
+import java.util.StringTokenizer;
+
+/**
+ * This class represents Universal Object Identifiers (Oids) and their + * associated operations.
+ * + *Oids are hierarchically globally-interpretable identifiers used + * within the GSS-API framework to identify mechanisms and name formats.
+ * + *The structure and encoding of Oids is defined in ISOIEC-8824 and + * ISOIEC-8825. For example the Oid representation of Kerberos V5 + * mechanism is "1.2.840.113554.1.2.2".
+ * + *The {@link GSSName} name class contains public static Oid
+ * objects representing the standard name types defined in GSS-API.