summaryrefslogtreecommitdiff
path: root/org/ietf
diff options
context:
space:
mode:
authorCasey Marshall <csm@gnu.org>2004-08-14 18:21:34 +0000
committerCasey Marshall <csm@gnu.org>2004-08-14 18:21:34 +0000
commit449f390a69782e6ea3bb48913f027da1dc04011a (patch)
tree397a5d08f77527b823150aaf01037bdff26130a4 /org/ietf
parent5593f57038abf197fb29aecfe42f2cb4d7ea3cb2 (diff)
downloadclasspath-449f390a69782e6ea3bb48913f027da1dc04011a.tar.gz
2004-08-14 Casey Marshall <csm@gnu.org>
The Big Crypto Merge of 2004. * lib/Makefile.am: updated for jgss resources. * lib/gen-classlist.sh.in: updated for classes in org/. * javax/security/auth/x500/X500Principal.java: replaced with GNU Crypto's version. * resource/org/Makefile.am, * resource/org/ietf/Makefile.am, * resource/org/ietf/jgss/Makefile.am: new files. Files imported from GNU Crypto. * javax/crypto/BadPaddingException.java * javax/crypto/Cipher.java * javax/crypto/CipherInputStream.java * javax/crypto/CipherOutputStream.java * javax/crypto/CipherSpi.java * javax/crypto/EncryptedPrivateKeyInfo.java * javax/crypto/ExemptionMechanism.java * javax/crypto/ExemptionMechanismException.java * javax/crypto/ExemptionMechanismSpi.java * javax/crypto/IllegalBlockSizeException.java * javax/crypto/KeyAgreement.java * javax/crypto/KeyAgreementSpi.java * javax/crypto/KeyGenerator.java * javax/crypto/KeyGeneratorSpi.java * javax/crypto/Mac.java * javax/crypto/MacSpi.java * javax/crypto/Makefile.am * javax/crypto/NoSuchPaddingException.java * javax/crypto/NullCipher.java * javax/crypto/NullCipherImpl.java * javax/crypto/SealedObject.java * javax/crypto/SecretKey.java * javax/crypto/SecretKeyFactory.java * javax/crypto/SecretKeyFactorySpi.java * javax/crypto/ShortBufferException.java * javax/crypto/interfaces/DHKey.java * javax/crypto/interfaces/DHPrivateKey.java * javax/crypto/interfaces/DHPublicKey.java * javax/crypto/interfaces/PBEKey.java * javax/crypto/spec/DESKeySpec.java * javax/crypto/spec/DESedeKeySpec.java * javax/crypto/spec/DHGenParameterSpec.java * javax/crypto/spec/DHParameterSpec.java * javax/crypto/spec/DHPrivateKeySpec.java * javax/crypto/spec/DHPublicKeySpec.java * javax/crypto/spec/IvParameterSpec.java * javax/crypto/spec/PBEKeySpec.java * javax/crypto/spec/PBEParameterSpec.java * javax/crypto/spec/RC2ParameterSpec.java * javax/crypto/spec/RC5ParameterSpec.java * javax/crypto/spec/SecretKeySpec.java * javax/security/auth/AuthPermission.java * javax/security/auth/DestroyFailedException.java * javax/security/auth/Destroyable.java * javax/security/auth/Policy.java * javax/security/auth/PrivateCredentialPermission.java * javax/security/auth/RefreshFailedException.java * javax/security/auth/Refreshable.java * javax/security/auth/Subject.java * javax/security/auth/SubjectDomainCombiner.java * javax/security/auth/callback/Callback.java * javax/security/auth/callback/CallbackHandler.java * javax/security/auth/callback/ChoiceCallback.java * javax/security/auth/callback/ConfirmationCallback.java * javax/security/auth/callback/LanguageCallback.java * javax/security/auth/callback/NameCallback.java * javax/security/auth/callback/PasswordCallback.java * javax/security/auth/callback/TextInputCallback.java * javax/security/auth/callback/TextOutputCallback.java * javax/security/auth/callback/UnsupportedCallbackException.java * javax/security/auth/login/AccountExpiredException.java * javax/security/auth/login/AppConfigurationEntry.java * javax/security/auth/login/Configuration.java * javax/security/auth/login/CredentialExpiredException.java * javax/security/auth/login/FailedLoginException.java * javax/security/auth/login/LoginContext.java * javax/security/auth/login/LoginException.java * javax/security/auth/login/NullConfiguration.java * javax/security/auth/x500/X500PrivateCredential.java * javax/security/sasl/AuthenticationException.java * javax/security/sasl/AuthorizeCallback.java * javax/security/sasl/RealmCallback.java * javax/security/sasl/RealmChoiceCallback.java * javax/security/sasl/Sasl.java * javax/security/sasl/SaslClient.java * javax/security/sasl/SaslClientFactory.java * javax/security/sasl/SaslException.java * javax/security/sasl/SaslServer.java * javax/security/sasl/SaslServerFactory.java * org/ietf/jgss/ChannelBinding.java * org/ietf/jgss/GSSContext.java * org/ietf/jgss/GSSCredential.java * org/ietf/jgss/GSSException.java * org/ietf/jgss/GSSManager.java * org/ietf/jgss/GSSName.java * org/ietf/jgss/MessageProp.java * org/ietf/jgss/Oid.java * resources/org/ietf/jgss/MessagesBundle.properties Files imported from Jessie <http://www.nongnu.org/jessie/> * javax/net/ServerSocketFactory.java * javax/net/SocketFactory.java * javax/net/VanillaServerSocketFactory.java * javax/net/VanillaSocketFactory.java * javax/net/ssl/HandshakeCompletedEvent.java * javax/net/ssl/HandshakeCompletedListener.java * javax/net/ssl/HostnameVerifier.java * javax/net/ssl/HttpsURLConnection.java * javax/net/ssl/KeyManager.java * javax/net/ssl/KeyManagerFactory.java * javax/net/ssl/KeyManagerFactorySpi.java * javax/net/ssl/ManagerFactoryParameters.java * javax/net/ssl/SSLContext.java * javax/net/ssl/SSLContextSpi.java * javax/net/ssl/SSLException.java * javax/net/ssl/SSLHandshakeException.java * javax/net/ssl/SSLKeyException.java * javax/net/ssl/SSLPeerUnverifiedException.java * javax/net/ssl/SSLPermission.java * javax/net/ssl/SSLProtocolException.java * javax/net/ssl/SSLServerSocket.java * javax/net/ssl/SSLServerSocketFactory.java * javax/net/ssl/SSLSession.java * javax/net/ssl/SSLSessionBindingEvent.java * javax/net/ssl/SSLSessionBindingListener.java * javax/net/ssl/SSLSessionContext.java * javax/net/ssl/SSLSocket.java * javax/net/ssl/SSLSocketFactory.java * javax/net/ssl/TrivialHostnameVerifier.java * javax/net/ssl/TrustManager.java * javax/net/ssl/TrustManagerFactory.java * javax/net/ssl/TrustManagerFactorySpi.java * javax/net/ssl/X509KeyManager.java * javax/net/ssl/X509TrustManager.java * javax/security/cert/Certificate.java * javax/security/cert/CertificateEncodingException.java * javax/security/cert/CertificateException.java * javax/security/cert/CertificateExpiredException.java * javax/security/cert/CertificateNotYetValidException.java * javax/security/cert/CertificateParsingException.java * javax/security/cert/X509CertBridge.java * javax/security/cert/X509Certificate.java
Diffstat (limited to 'org/ietf')
-rw-r--r--org/ietf/jgss/ChannelBinding.java215
-rw-r--r--org/ietf/jgss/GSSContext.java924
-rw-r--r--org/ietf/jgss/GSSCredential.java334
-rw-r--r--org/ietf/jgss/GSSException.java431
-rw-r--r--org/ietf/jgss/GSSManager.java501
-rw-r--r--org/ietf/jgss/GSSName.java269
-rw-r--r--org/ietf/jgss/MessageProp.java273
-rw-r--r--org/ietf/jgss/Oid.java385
8 files changed, 3332 insertions, 0 deletions
diff --git a/org/ietf/jgss/ChannelBinding.java b/org/ietf/jgss/ChannelBinding.java
new file mode 100644
index 000000000..9e966d54a
--- /dev/null
+++ b/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;
+
+/**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ */
+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. <code>null</code> values can be used for any fields which the
+ * application does not want to specify.
+ *
+ * @param initAddr The address of the context initiator. <code>null</code>
+ * value can be supplied to indicate that the application
+ * does not want to set this value.
+ * @param acceptAddr The address of the context acceptor. <code>null</code>
+ * 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. <code>null</code> 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.
+ * <code>null</code> is returned if the address has not been set.
+ *
+ * @return The initiator's address, or <code>null</code>.
+ */
+ public InetAddress getInitiatorAddress()
+ {
+ return initAddr;
+ }
+
+ /**
+ * Returns the acceptor's address for this channel binding.
+ * <code>null</code> is returned if the address has not been set.
+ *
+ * @return The acceptor's address, or <code>null</code>.
+ */
+ public InetAddress getAcceptorAddress()
+ {
+ return acceptAddr;
+ }
+
+ /**
+ * Returns application data being used as part of the ChannelBinding.
+ * <code>null</code> is returned if no application data has been
+ * specified for the channel binding.
+ *
+ * @return The application data, or <code>null</code>.
+ */
+ public byte[] getApplicationData()
+ {
+ if (appData != null)
+ return (byte[]) appData.clone();
+ return null;
+ }
+
+ /**
+ * Returns <code>true</code> 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/org/ietf/jgss/GSSContext.java b/org/ietf/jgss/GSSContext.java
new file mode 100644
index 000000000..ab09c31c5
--- /dev/null
+++ b/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;
+
+/**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>After the context has been established or the {@link #isProtReady()}
+ * method returns <code>true</code>, 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.</p>
+ *
+ * <p>When the context is no longer needed, the application should call
+ * {@link dispose()} to release any system resources the context may be
+ * using.</p>
+ *
+ * <h3>Example Code</h3>
+ *
+ * <pre>
+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();
+ * </pre>
+ */
+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.
+ // -------------------------------------------------------------------------
+
+ /**
+ * <p>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
+ * <code>false</code> 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 <code>true</code> also.
+ * This indicates that the token needs to be sent to the peer, but the local
+ * end of the context is now fully established.</p>
+ *
+ * <p>Upon completion of the context establishment, the available context
+ * options may be queried through the get methods.</p>
+ *
+ * @param inputBuf Token generated by the peer. This parameter is ignored
+ * on the first call.
+ * @param offset The offset within the <i>inputBuf</i> where the token
+ * begins.
+ * @param len The length of the token within the <i>inputBuf</i>
+ * (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;
+
+ /**
+ * <p>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 <i>outStream</i>, 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 <code>false</code> 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 <code>true</code> also. This indicates that
+ * the token needs to be sent to the peer, but the local end of the context
+ * is now fully established.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>Upon completion of the context establishment, the available context
+ * options may be queried through the get methods.</p>
+ *
+ * @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 <i>outStream</i>, or 0 if no
+ * token is written.
+ * @throws GSSException If this operation fails.
+ */
+ int initSecContext(InputStream inStream, OutputStream outStream)
+ throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>This method may return an output token which the application will
+ * need to send to the peer for further processing by the init call.</p>
+ *
+ * <p><code>null</code> 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 <code>false</code> from {@link #isEstablished()}
+ * indicates that more tokens are expected to be supplied to this
+ * method.</p>
+ *
+ * <p>Note that it is possible that acceptSecContext() return a token for
+ * the peer, and isEstablished() return <code>true</code> also. This
+ * indicates that the token needs to be sent to the peer, but the local
+ * end of the context is now fully established.</p>
+ *
+ * <p>Upon completion of the context establishment, the available context
+ * options may be queried through the get methods.</p>
+ *
+ * @param inTok Token generated by the peer.
+ * @param offset The offset within the <i>inTok</i> where the token begins.
+ * @param len The length of the token within the <i>inTok</i> (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;
+
+ /**
+ * <p>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 <code>false</code> from
+ * {@link #isEstablished()} indicates that more tokens are expected to be
+ * supplied to this method.</p>
+ *
+ * <p>Note that it is possible that acceptSecContext() return a token for
+ * the peer, and isEstablished() return <code>true</code> also. This
+ * indicates that the token needs to be sent to the peer, but the local
+ * end of the context is now fully established.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>Upon completion of the context establishment, the available context
+ * options may be queried through the get methods.</p>
+ *
+ * @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. Returns <code>true</code> 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;
+
+ /**
+ * <p>Returns the maximum message size that, if presented to the
+ * {@link #wrap(byte[],int,int,org.ietf.jgss.MessageProp)} method with
+ * the same <i>confReq</i> and <i>qop</i> parameters, will result in an
+ * output token containing no more than the <i>maxTokenSize</i> bytes.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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 <i>inBuf</i>. This method is
+ * equivalent in functionality to its stream counterpart. The returned
+ * byte array will contain both the MIC and the message.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>The application will be responsible for sending the token to the
+ * peer.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>The application will be responsible for sending the token to the
+ * peer.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>Note that privacy can only be applied through the wrap call.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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 in <code>null</code> 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;
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>Note that privacy can only be applied through the wrap call.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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 in <code>null</code> for msgProp
+ * to request default QOP.
+ * @throws GSSException If this operation fails.
+ */
+ void getMIC(InputStream inStream, OutputStream outStream, MessageProp mgProp)
+ throws GSSException;
+
+ /**
+ * <p>Verifies the cryptographic MIC, contained in the token parameter,
+ * over the supplied message. This method is equivalent in
+ * functionality to its stream counterpart.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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 to <code>false</code>.
+ * @throws GSSException If this operation fails.
+ */
+ void verifyMIC(byte[] inTok, int tokOffset, int tokLen, byte[] inMsg,
+ int msgOffset, int msgLen, MessageProp msgProp)
+ throws GSSException;
+
+ /**
+ * <p>Verifies the cryptographic MIC, contained in the token parameter,
+ * over the supplied message. This method is equivalent in
+ * functionality to its byte array counterpart.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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 to <code>false</code>.
+ * @throws GSSException If this operation fails.
+ */
+ void verifyMIC(InputStream tokStream, InputStream msgStream, MessageProp msgProp)
+ throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * @return The exported context.
+ * @throws GSSException If this operation fails.
+ */
+ byte[] export() throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * @param state Boolean representing if credential delegation is
+ * desired.
+ * @throws GSSException If this operation fails.
+ */
+ void requestCredDeleg(boolean state) throws GSSException;
+
+ /**
+ * <p>Requests anonymous support over the context. This method is only
+ * valid before the context creation process begins and only for the
+ * initiator.</p>
+ *
+ * @param state Boolean representing if anonymity support is requested.
+ * @throws GSSException If this operation fails.
+ */
+ void requestAnonymity(boolean state) throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * @param lifetime The desired context lifetime in seconds.
+ * @throws GSSException If this operation fails.
+ */
+ void requestLifetime(int lifetime) throws GSSException;
+
+ /**
+ * <p>Sets the channel bindings to be used during context establishment.
+ * This method is only valid before the context creation process begins.</p>
+ *
+ * @param cb Channel bindings to be used.
+ * @throws GSSException If this operation fails.
+ */
+ void setChannelBinding(ChannelBinding cb) throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The state of the delegated credentials for the context.
+ */
+ boolean getCredDelegState();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The state of the mutual authentication option.
+ */
+ boolean getMutualAuthState();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The state of the replay detection option.
+ */
+ boolean getReplayDetState();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The state of the sequence detection option.
+ */
+ boolean getSequenceDetState();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return True if this is an anonymous context.
+ */
+ boolean getAnonymityState();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return True if the context is transferable.
+ * @throws GSSException If this operation fails.
+ */
+ boolean isTransferable() throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * @return True if the per message operations can be applied over
+ * the context.
+ */
+ boolean isProtReady();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return True the confidentiality service state.
+ */
+ boolean getConfState();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The integrity service state.
+ */
+ boolean getIntegState();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The lifetime.
+ */
+ int getLifetime();
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The name of the context initiator.
+ * @throws GSSException If this operation fails.
+ */
+ GSSName getSrcName() throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The name of the context target.
+ * @throws GSSException If this operation fails.
+ */
+ GSSName getTargName() throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The mechanism OID.
+ * @throws GSSException If this operation fails.
+ */
+ Oid getMech() throws GSSException;
+
+ /**
+ * <p>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.</p>
+ *
+ * @return The delegated credential object.
+ * @throws GSSException If this operation fails.
+ */
+ GSSCredential getDelegCred() throws GSSException;
+
+ /**
+ * <p>Returns "true" if this is the initiator of the context. This call is
+ * only valid after the context creation process has started.</p>
+ *
+ * @return True if this is the initiator.
+ * @throws GSSException If this operation fails.
+ */
+ boolean isInitiator() throws GSSException;
+}
diff --git a/org/ietf/jgss/GSSCredential.java b/org/ietf/jgss/GSSCredential.java
new file mode 100644
index 000000000..318848ec9
--- /dev/null
+++ b/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;
+
+/**
+ * <p>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.</p>
+ *
+ * <p>A credential may be used to perform context initiation, acceptance,
+ * or both.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <h3>Example Code</h3>
+ *
+ * <pre>
+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();
+ * </pre>
+ */
+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;
+
+ /**
+ * <p>Adds a mechanism specific credential-element to an existing
+ * credential. This method allows the construction of credentials one
+ * mechanism at a time.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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 <code>add()</code>
+ * method.</p>
+ *
+ * @param aName Name of the principal for whom this credential
+ * is to be acquired. Use <code>null</code> 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 <code>true</code>
+ * if the two GSSCredentials refer to the same entity; <code>false</code>
+ * 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/org/ietf/jgss/GSSException.java b/org/ietf/jgss/GSSException.java
new file mode 100644
index 000000000..72d91c0da
--- /dev/null
+++ b/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.
+ * <code>null</code> will be returned when no mechanism error code has
+ * been set.
+ *
+ * @return The minor error string, or <code>null</code>.
+ */
+ 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/org/ietf/jgss/GSSManager.java b/org/ietf/jgss/GSSManager.java
new file mode 100644
index 000000000..26fdd14b6
--- /dev/null
+++ b/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;
+
+/**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>It is envisioned that there will be three most common ways in which
+ * providers will be used:</p>
+ *
+ * <ol>
+ * <li>The application does not care about what provider is used (the
+ * default case).</li>
+ *
+ * <li>The application wants a particular provider to be used
+ * preferentially, either for a particular mechanism or all the
+ * time, irrespective of mechanism.</li>
+ *
+ * <li>The application wants to use the locally configured providers
+ * as far as possible but if support is missing for one or more
+ * mechanisms then it wants to fall back on its own provider.</li>
+ * </ol>
+ *
+ * <p>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
+ * (<i>provider</i>, <i>oid</i>) pairs where each pair indicates a preference
+ * of provider for a given oid.</p>
+ *
+ * <p>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.</p>
+ *
+ * <h3>Example Code</h3>
+ *
+ * <pre>
+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);
+</pre>
+ */
+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.
+ // -------------------------------------------------------------------------
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>If there are any previously existing preferences that conflict with
+ * the preference being set here, then the GSSManager should ignore this
+ * request.</p>
+ *
+ * <p>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.</p>
+ *
+ * @param p The provider instance that should be used whenever
+ * support is needed for <i>mech</i>.
+ * @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;
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * @param p The provider instance that should be used whenever
+ * support is needed for <i>mech</i>.
+ * @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. Use <code>null</code> 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 <code>null</code>
+ * to request default mechanism.
+ * @param myCred Credentials of the initiator. Use <code>null</code>
+ * 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 <code>null</code> 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 <code>null</code>
+ * 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code>.
+ */
+ public abstract Oid[] getMechs();
+
+ /**
+ * Returns an array of {@link Oid} objects corresponding to the mechanisms
+ * that support the specific name type. <code>null</code> 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 <code>null</code>.
+ */
+ 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/org/ietf/jgss/GSSName.java b/org/ietf/jgss/GSSName.java
new file mode 100644
index 000000000..fd158a900
--- /dev/null
+++ b/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;
+
+/**
+ * <p>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.</p>
+ *
+ * <h3>Example Code</h3>
+ *
+ * <pre>
+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);
+</pre>
+ */
+public interface GSSName
+{
+
+ // Constants.
+ // -------------------------------------------------------------------------
+
+ /**
+ * <p>Name type for representing an anonymous entity. It represents the
+ * following value: <code>{ 1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name) }</code>.</p>
+ */
+ Oid NT_ANONYMOUS = new Oid(new int[] { 1, 3, 6, 1, 5, 6, 3 });
+
+ /**
+ * <p>Name type used to indicate an exported name produced by the export
+ * method. It represents the following value: <code>{ 1(iso), 3(org), 6(dod),
+ * 1(internet), 5(security), 6(nametypes), 4(gss-api-exported-name)
+ * }</code>.</p>
+ */
+ Oid NT_EXPORT_NAME = new Oid(new int[] { 1, 3, 6, 1, 5, 6, 4 });
+
+ /**
+ * <p>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:</p>
+ *
+ * <blockquote><code>service@hostname</code></blockquote>
+ *
+ * <p>Values for the "service" element are registered with the IANA. It
+ * represents the following value: <code>{ 1(iso), 3(org), 6(dod),
+ * 1(internet), 5(security), 6(nametypes), 2(gss-host-based-services)
+ * }</code>.</p>
+ */
+ Oid NT_HOSTBASED_SERVICE = new Oid(new int[] { 1, 3, 6, 1, 5, 6, 2 });
+
+ /**
+ * <p>Name type to indicate a numeric user identifier corresponding to a
+ * user on a local system. (e.g. Uid). It represents the following
+ * value: <code>{ iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2) }</code>.</p>
+ */
+ Oid NT_MACHINE_UID_NAME = new Oid(new int[] { 1, 2, 840, 113554, 1, 2, 1, 2 });
+
+ /**
+ * <p>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: <code>{ iso(1) member-body(2) United States(840)
+ * mit(113554) infosys(1) gssapi(2) generic(1) string_uid_name(3)
+ * }</code>.</p>
+ */
+ Oid NT_STRING_UID_NAME = new Oid(new int[] { 1, 2, 840, 113554, 1, 2, 1, 3 });
+
+ /**
+ * <p>Name type to indicate a named user on a local system. It represents
+ * the following value: <code>{ iso(1) member-body(2) United States(840)
+ * mit(113554) infosys(1) gssapi(2) generic(1) user_name(1) }</code>.</p>
+ */
+ Oid NT_USER_NAME = new Oid(new int[] { 1, 2, 840, 113554, 1, 2, 1, 1 });
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Compares two GSSName objects to determine whether they refer to the
+ * same entity. This method may throw a {@link GSSException} when the
+ * names cannot be compared. If either of the names represents an
+ * anonymous entity, the method will return <code>false</code>.
+ *
+ * @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, <code>false</code> 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 <a
+ * href="http://www.ietf.org/rfc/rfc2743.txt">RFC 2743</a>.
+ *
+ * @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
+ * <code>true</code> 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 <a
+ * href="http://www.ietf.org/rfc/rfc2743.txt">RFC 2743</a>.
+ *
+ * @return True if this name is a mechanism name.
+ */
+ boolean isMN();
+}
diff --git a/org/ietf/jgss/MessageProp.java b/org/ietf/jgss/MessageProp.java
new file mode 100644
index 000000000..a3fd22e55
--- /dev/null
+++ b/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;
+
+/**
+ * <p>This is a utility class used within the per-message {@link
+ * GSSContext} methods to convey per-message properties.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ */
+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.
+ // -------------------------------------------------------------------------
+
+ /**
+ * <p>Constructor which sets QOP to 0 indicating that the default QOP is
+ * requested.</p>
+ *
+ * @param privState The desired privacy state. "true" for privacy and
+ * "false" for integrity only.
+ */
+ public MessageProp(boolean privState)
+ {
+ this(0, privState);
+ }
+
+ /**
+ * <p>Constructor which sets the values for the qop and privacy state.</p>
+ *
+ * @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.
+ * <code>null</code> 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/org/ietf/jgss/Oid.java b/org/ietf/jgss/Oid.java
new file mode 100644
index 000000000..a7c67a710
--- /dev/null
+++ b/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;
+
+/**
+ * <p>This class represents Universal Object Identifiers (Oids) and their
+ * associated operations.</p>
+ *
+ * <p>Oids are hierarchically globally-interpretable identifiers used
+ * within the GSS-API framework to identify mechanisms and name formats.</p>
+ *
+ * <p>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".</p>
+ *
+ * <p>The {@link GSSName} name class contains <code>public static Oid</code>
+ * objects representing the standard name types defined in GSS-API.</p>
+ */
+public class Oid
+{
+
+ // Constants and fields.
+ // -------------------------------------------------------------------------
+
+ private static final int OBJECT_IDENTIFIER = 0x06;
+ private static final int RELATIVE_OID = 0x0d;
+
+ private final int[] components;
+ private byte[] derOid;
+ private String strOid;
+ private boolean relative;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Creates an Oid object from a string representation of its integer
+ * components (e.g. "1.2.840.113554.1.2.2").
+ *
+ * @param strOid The string representation for the oid.
+ * @throws GSSException If the argument is badly formed.
+ */
+ public Oid(String strOid) throws GSSException
+ {
+ if (strOid == null)
+ throw new NullPointerException();
+ this.strOid = strOid;
+ try
+ {
+ StringTokenizer tok = new StringTokenizer(strOid, ".");
+ components = new int[tok.countTokens()];
+ int i = 0;
+ while (tok.hasMoreTokens() && i < components.length)
+ {
+ components[i++] = Integer.parseInt(tok.nextToken());
+ }
+ }
+ catch (Exception x)
+ {
+ throw new GSSException(GSSException.FAILURE);
+ }
+ relative = false;
+ }
+
+ /**
+ * Creates an Oid object from its DER encoding. This refers to the full
+ * encoding including tag and length. The structure and encoding of
+ * Oids is defined in ISOIEC-8824 and ISOIEC-8825. This method is
+ * identical in functionality to its byte array counterpart.
+ *
+ * @param derOid Stream containing the DER encoded oid.
+ * @throws GSSException If the DER stream is badly formed, or if the
+ * input stream throws an exception.
+ */
+ public Oid(InputStream derOid) throws GSSException
+ {
+ DataInputStream in = new DataInputStream(derOid);
+ try
+ {
+ int tag = in.read() & 0x1F;
+ if (tag != OBJECT_IDENTIFIER && tag != RELATIVE_OID)
+ throw new IOException();
+ int len = in.read();
+ if ((len & ~0x7F) != 0)
+ {
+ byte[] buf = new byte[len & 0x7F];
+ in.readFully(buf);
+ len = new BigInteger(1, buf).intValue();
+ }
+ if (len < 0)
+ throw new IOException();
+ byte[] enc = new byte[len];
+ in.readFully(enc);
+ int[] comp = new int[len + 1];
+ int count = 0;
+ int i = 0;
+ relative = tag == RELATIVE_OID;
+ if (!relative && i < len)
+ {
+ int j = (enc[i] & 0xFF);
+ comp[count++] = j / 40;
+ comp[count++] = j % 40;
+ i++;
+ }
+ while (i < len)
+ {
+ int j = 0;
+ do
+ {
+ j = enc[i++] & 0xFF;
+ comp[count] <<= 7;
+ comp[count] |= j & 0x7F;
+ if (i >= len && (j & 0x80) != 0)
+ throw new IOException();
+ }
+ while ((j & 0x80) != 0);
+ count++;
+ }
+ if (count == len)
+ this.components = comp;
+ else
+ {
+ this.components = new int[count];
+ System.arraycopy(comp, 0, components, 0, count);
+ }
+ }
+ catch (IOException ioe)
+ {
+ throw new GSSException(GSSException.FAILURE);
+ }
+ }
+
+ /**
+ * Creates an Oid object from its DER encoding. This refers to the full
+ * encoding including tag and length. The structure and encoding of
+ * Oids is defined in ISOIEC-8824 and ISOIEC-8825. This method is
+ * identical in functionality to its streaming counterpart.
+ *
+ * @param derOid Byte array storing a DER encoded oid.
+ * @throws GSSException If the DER bytes are badly formed.
+ */
+ public Oid(byte[] derOid) throws GSSException
+ {
+ this(new ByteArrayInputStream(derOid));
+ this.derOid = (byte[]) derOid.clone();
+ }
+
+ Oid(int[] components)
+ {
+ this.components = components;
+ relative = false;
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns a string representation of the oid's integer components in
+ * dot separated notation (e.g. "1.2.840.113554.1.2.2").
+ *
+ * @return The string representation of this oid.
+ */
+ public String toString()
+ {
+ if (strOid == null)
+ {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < components.length; i++)
+ {
+ buf.append(components[i]);
+ if (i < components.length - 1)
+ buf.append('.');
+ }
+ strOid = buf.toString();
+ }
+ return strOid;
+ }
+
+ /**
+ * Returns the full ASN.1 DER encoding for this oid object, which
+ * includes the tag and length.
+ *
+ * @return The ASN.1 DER encoding for this oid.
+ * @throws GSSException If encoding fails.
+ */
+ public byte[] getDER() throws GSSException
+ {
+ if (derOid == null)
+ {
+ ByteArrayOutputStream out = new ByteArrayOutputStream(256);
+ try
+ {
+ int i = 0;
+ if (!relative)
+ {
+ int b = components[i++] * 40 + (components.length > 1
+ ? components[i++] : 0);
+ encodeSubId(out, b);
+ }
+ for ( ; i < components.length; i++)
+ encodeSubId(out, components[i]);
+ byte[] oid = out.toByteArray();
+ out.reset();
+ if (relative)
+ out.write(RELATIVE_OID);
+ else
+ out.write(OBJECT_IDENTIFIER);
+ if (oid.length < 128)
+ out.write(oid.length);
+ else if (oid.length < 256)
+ {
+ out.write(0x81);
+ out.write(oid.length);
+ }
+ else if (oid.length < 65536)
+ {
+ out.write(0x82);
+ out.write((oid.length >>> 8) & 0xFF);
+ out.write(oid.length & 0xFF);
+ }
+ else if (oid.length < 16777216)
+ {
+ out.write(0x83);
+ out.write((oid.length >>> 16) & 0xFF);
+ out.write((oid.length >>> 8) & 0xFF);
+ out.write(oid.length & 0xFF);
+ }
+ else
+ {
+ out.write(0x84);
+ out.write((oid.length >>> 24) & 0xFF);
+ out.write((oid.length >>> 16) & 0xFF);
+ out.write((oid.length >>> 8) & 0xFF);
+ out.write(oid.length & 0xFF);
+ }
+ out.write(oid);
+ }
+ catch (IOException ioe)
+ {
+ throw new GSSException(GSSException.FAILURE);
+ }
+ derOid = out.toByteArray();
+ }
+ return (byte[]) derOid.clone();
+ }
+
+ /**
+ * A utility method to test if an Oid object is contained within the
+ * supplied Oid object array.
+ *
+ * @param oids An array of oids to search.
+ * @return True if this oid is contained in the given array.
+ */
+ public boolean containedIn(Oid[] oids)
+ {
+ for (int i = 0; i < oids.length; i++)
+ {
+ if (equals(oids[i]))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof Oid))
+ return false;
+ Oid that = (Oid) o;
+ return Arrays.equals(components, that.components);
+ }
+
+ public int hashCode()
+ {
+ int code = 0;
+ for (int i = 0; i < components.length; i++)
+ code += components[i];
+ return code;
+ }
+
+ // Own methods.
+ // -------------------------------------------------------------------------
+
+ private static void encodeSubId(OutputStream out, int id) throws IOException
+ {
+ if (id < 128)
+ {
+ out.write(id);
+ }
+ else if (id < 16384)
+ {
+ out.write((id >>> 7) | 0x80);
+ out.write(id & 0x7F);
+ }
+ else if (id < 2097152)
+ {
+ out.write((id >>> 14) | 0x80);
+ out.write(((id >>> 7) | 0x80) & 0xFF);
+ out.write(id & 0x7F);
+ }
+ else if (id < 268435456)
+ {
+ out.write( (id >>> 21) | 0x80);
+ out.write(((id >>> 14) | 0x80) & 0xFF);
+ out.write(((id >>> 7) | 0x80) & 0xFF);
+ out.write(id & 0x7F);
+ }
+ }
+}