diff options
author | Andreas Tobler <a.tobler@schweiz.ch> | 2004-09-21 10:33:35 +0200 |
---|---|---|
committer | Andreas Tobler <andreast@gcc.gnu.org> | 2004-09-21 10:33:35 +0200 |
commit | 6f5ce93bab1c1ce6df0e71aa450f841f3d979bbc (patch) | |
tree | 9ec0d44b2435653b3e450bf4293546636a609d31 /libjava/org | |
parent | c93320c457dc75596c5482cdbef7783ad6cdaf2e (diff) | |
download | gcc-6f5ce93bab1c1ce6df0e71aa450f841f3d979bbc.zip gcc-6f5ce93bab1c1ce6df0e71aa450f841f3d979bbc.tar.gz gcc-6f5ce93bab1c1ce6df0e71aa450f841f3d979bbc.tar.bz2 |
[multiple changes]
2004-09-21 Andreas Tobler <a.tobler@schweiz.ch>
Import the big Crypto/Jessie/Security merge from Classpath.
* Makefile.am: Add imported files.
* Makefile.in: Regenerate.
2004-08-14 Casey Marshall <csm@gnu.org>
The Big Crypto Merge of 2004.
* javax/security/auth/x500/X500Principal.java: Replaced with GNU
Crypto's version.
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
* 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
2004-08-20 Casey Marshall <csm@gnu.org>
* java/security/cert/X509CRLSelector.java: New file.
* java/security/cert/X509CertSelector.java: New file.
From-SVN: r87795
Diffstat (limited to 'libjava/org')
-rw-r--r-- | libjava/org/ietf/jgss/ChannelBinding.java | 215 | ||||
-rw-r--r-- | libjava/org/ietf/jgss/GSSContext.java | 924 | ||||
-rw-r--r-- | libjava/org/ietf/jgss/GSSCredential.java | 334 | ||||
-rw-r--r-- | libjava/org/ietf/jgss/GSSException.java | 431 | ||||
-rw-r--r-- | libjava/org/ietf/jgss/GSSManager.java | 501 | ||||
-rw-r--r-- | libjava/org/ietf/jgss/GSSName.java | 269 | ||||
-rw-r--r-- | libjava/org/ietf/jgss/MessageProp.java | 273 | ||||
-rw-r--r-- | libjava/org/ietf/jgss/MessagesBundle.properties | 60 | ||||
-rw-r--r-- | libjava/org/ietf/jgss/Oid.java | 385 |
9 files changed, 3392 insertions, 0 deletions
diff --git a/libjava/org/ietf/jgss/ChannelBinding.java b/libjava/org/ietf/jgss/ChannelBinding.java new file mode 100644 index 0000000..9e966d5 --- /dev/null +++ b/libjava/org/ietf/jgss/ChannelBinding.java @@ -0,0 +1,215 @@ +/* ChannelBinding.java -- a channel binding in the GSS-API. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* The documentation comments of this class are derived from the text + of RFC 2853: Generic Security Service API Version 2: Java Bindings. + That document is covered under the following license notice: + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it +or assist in its implementation may be prepared, copied, published and +distributed, in whole or in part, without restriction of any kind, +provided that the above copyright notice and this paragraph are +included on all such copies and derivative works. However, this +document itself may not be modified in any way, such as by removing +the copyright notice or references to the Internet Society or other +Internet organizations, except as needed for the purpose of developing +Internet standards in which case the procedures for copyrights defined +in the Internet Standards process must be followed, or as required to +translate it into languages other than English. + +The limited permissions granted above are perpetual and will not be +revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on an +"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN +WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ + + +package org.ietf.jgss; + +import java.net.InetAddress; +import java.util.Arrays; + +/** + * <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/libjava/org/ietf/jgss/GSSContext.java b/libjava/org/ietf/jgss/GSSContext.java new file mode 100644 index 0000000..ab09c31 --- /dev/null +++ b/libjava/org/ietf/jgss/GSSContext.java @@ -0,0 +1,924 @@ +/* GSSContext.java -- The GSS context interface. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package org.ietf.jgss; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * <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/libjava/org/ietf/jgss/GSSCredential.java b/libjava/org/ietf/jgss/GSSCredential.java new file mode 100644 index 0000000..318848e --- /dev/null +++ b/libjava/org/ietf/jgss/GSSCredential.java @@ -0,0 +1,334 @@ +/* GSSCredential.java -- GSS credential interface. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* The documentation comments of this class are derived from the text + of RFC 2853: Generic Security Service API Version 2: Java Bindings. + That document is covered under the following license notice: + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it +or assist in its implementation may be prepared, copied, published and +distributed, in whole or in part, without restriction of any kind, +provided that the above copyright notice and this paragraph are +included on all such copies and derivative works. However, this +document itself may not be modified in any way, such as by removing +the copyright notice or references to the Internet Society or other +Internet organizations, except as needed for the purpose of developing +Internet standards in which case the procedures for copyrights defined +in the Internet Standards process must be followed, or as required to +translate it into languages other than English. + +The limited permissions granted above are perpetual and will not be +revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on an +"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN +WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ + + +package org.ietf.jgss; + +/** + * <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/libjava/org/ietf/jgss/GSSException.java b/libjava/org/ietf/jgss/GSSException.java new file mode 100644 index 0000000..72d91c0 --- /dev/null +++ b/libjava/org/ietf/jgss/GSSException.java @@ -0,0 +1,431 @@ +/* GSSException.java -- a general exception in GSS. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* The documentation comments of this class are derived from the text + of RFC 2853: Generic Security Service API Version 2: Java Bindings. + That document is covered under the following license notice: + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it +or assist in its implementation may be prepared, copied, published and +distributed, in whole or in part, without restriction of any kind, +provided that the above copyright notice and this paragraph are +included on all such copies and derivative works. However, this +document itself may not be modified in any way, such as by removing +the copyright notice or references to the Internet Society or other +Internet organizations, except as needed for the purpose of developing +Internet standards in which case the procedures for copyrights defined +in the Internet Standards process must be followed, or as required to +translate it into languages other than English. + +The limited permissions granted above are perpetual and will not be +revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on an +"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN +WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ + + +package org.ietf.jgss; + +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; + +/** + * This exception is thrown whenever a fatal GSS-API error occurs + * including mechanism specific errors. It may contain both, the major + * and minor, GSS-API status codes. The mechanism implementers are + * responsible for setting appropriate minor status codes when throwing + * this exception. Aside from delivering the numeric error code(s) to + * the caller, this class performs the mapping from their numeric values + * to textual representations. All Java GSS-API methods are declared + * throwing this exception. + */ +public class GSSException extends Exception +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + // These values do not jive with the "Constant Field Values" in the J2SE + // 1.4.1, but do follow RFC 2853. I trust the IETF, but not Sun. + + /** + * Channel bindings mismatch error. + */ + public static final int BAD_BINDINGS = 4; + + /** + * Unsupported mechanism requested error. + */ + public static final int BAD_MECH = 1; + + /** + * Invalid name provided error. + */ + public static final int BAD_NAME = 2; + + /** + * Name of unsupported type provided error. + */ + public static final int BAD_NAMETYPE = 3; + + /** + * Invalid status code error - this is the default status value. + */ + public static final int BAD_STATUS = 5; + + /** + * Token had invalid integrity check error. + */ + public static final int BAD_MIC = 6; + + /** + * Specified security context expired error. + */ + public static final int CONTEXT_EXPIRED = 12; + + /** + * Expired credentials detected error. + */ + public static final int CREDENTIALS_EXPIRED = 11; + + /** + * Defective credential error. + */ + public static final int DEFECTIVE_CREDENTIAL = 10; + + /** + * Defective token error. + */ + public static final int DEFECTIVE_TOKEN = 9; + + /** + * General failure, unspecified at GSS-API level. + */ + public static final int FAILURE = 13; + + /** + * Invalid security context error. + */ + public static final int NO_CONTEXT = 8; + + /** + * Invalid credentials error. + */ + public static final int NO_CRED = 7; + + /** + * Unsupported QOP value error. + */ + public static final int BAD_QOP = 14; + + /** + * Operation unauthorized error. + */ + public static final int UNAUTHORIZED = 15; + + /** + * Operation unavailable error. + */ + public static final int UNAVAILABLE = 16; + + /** + * Duplicate credential element requested error. + */ + public static final int DUPLICATE_ELEMENT = 17; + + /** + * Name contains multi-mechanism elements error. + */ + public static final int NAME_NOT_MN = 18; + + /** + * The token was a duplicate of an earlier token. This is a fatal error + * code that may occur during context establishment. It is not used to + * indicate supplementary status values. The MessageProp object is used + * for that purpose. + */ + public static final int DUPLICATE_TOKEN = 20; + + /** + * The token's validity period has expired. This is a fatal error code + * that may occur during context establishment. It is not used to + * indicate supplementary status values. The MessageProp object is used + * for that purpose. + */ + public static final int OLD_TOKEN = 19; + + /** + * A later token has already been processed. This is a fatal error code + * that may occur during context establishment. It is not used to + * indicate supplementary status values. The MessageProp object is used + * for that purpose. + */ + public static final int UNSEQ_TOKEN = 21; + + /** + * An expected per-message token was not received. This is a fatal + * error code that may occur during context establishment. It is not + * used to indicate supplementary status values. The MessageProp object + * is used for that purpose. + */ + public static final int GAP_TOKEN = 22; + + private final int major; + private int minor; + private String minorString; + + private ResourceBundle messages; + + // Constructors. + // ------------------------------------------------------------------------- + + /** + * Create a new GSS exception with the given major code. + * + * @param major The major GSS error code. + */ + public GSSException(int major) + { + this(major, 0, null); + } + + /** + * Create a new GSS exception with the given major and minor codes, and a + * minor explanation string. + * + * @param major The major GSS error code. + * @param minor The minor application-specific error code. + * @param minorString An explanation of the minor error code. + */ + public GSSException(int major, int minor, String minorString) + { + this.major = major; + this.minor = minor; + this.minorString = minorString; + try + { + messages = PropertyResourceBundle.getBundle("org/ietf/jgss/MessagesBundle"); + } + catch (Exception e) + { + messages = null; + } + } + + // Instance methods. + // ------------------------------------------------------------------------- + + /** + * Returns the major code representing the GSS error code that caused + * this exception to be thrown. + * + * @return The major error code. + */ + public int getMajor() + { + return major; + } + + /** + * Returns the mechanism error code that caused this exception. The + * minor code is set by the underlying mechanism. Value of 0 indicates + * that mechanism error code is not set. + * + * @return The minor error code, or 0 if not set. + */ + public int getMinor() + { + return minor; + } + + /** + * Returns a string explaining the GSS major error code causing this + * exception to be thrown. + * + * @return The major error string. + */ + public String getMajorString() + { + switch (major) + { + case BAD_MECH: + return getMsg("GSSException.BAD_MECH", + "An unsupported mechanism was requested."); + case BAD_NAME: + return getMsg("GSSException.BAD_NAME", + "An invalid name was supplied."); + case BAD_NAMETYPE: + return getMsg("GSSException.BAD_NAMETYPE", + "A supplied name was of an unsupported type."); + case BAD_BINDINGS: + return getMsg("GSSException.BAD_BINDINGS", + "Incorrect channel bindings were supplied."); + case BAD_STATUS: + return getMsg("GSSException.BAD_STATUS", + "An invalid status code was supplied."); + case BAD_MIC: + return getMsg("GSSException.BAD_MIC", + "A token had an invalid MIC."); + case NO_CRED: + return getMsg("GSSException.NO_CRED", + "No credentials were supplied, or the credentials were "+ + "unavailable or inaccessible."); + case NO_CONTEXT: + return getMsg("GSSException.NO_CONTEXT", + "Invalid context has been supplied."); + case DEFECTIVE_TOKEN: + return getMsg("GSSException.DEFECTIVE_TOKEN", + "A supplied token was invalid."); + case DEFECTIVE_CREDENTIAL: + return getMsg("GSSException.DEFECTIVE_CREDENTIAL", + "A supplied credential was invalid."); + case CREDENTIALS_EXPIRED: + return getMsg("GSSException.CREDENTIALS_EXPIRED", + "The referenced credentials have expired."); + case CONTEXT_EXPIRED: + return getMsg("GSSException.CONTEXT_EXPIRED", + "The context has expired."); + case FAILURE: + return getMsg("GSSException.FAILURE", + "Miscellaneous failure."); + case BAD_QOP: + return getMsg("GSSException.BAD_QOP", + "The quality-of-protection requested could not be provided."); + case UNAUTHORIZED: + return getMsg("GSSException.UNAUTHORIZED", + "The operation is forbidden by local security policy."); + case UNAVAILABLE: + return getMsg("GSSException.UNAVAILABLE", + "The operation or option is unavailable."); + case DUPLICATE_ELEMENT: + return getMsg("GSSException.DUPLICATE_ELEMENT", + "The requested credential element already exists."); + case NAME_NOT_MN: + return getMsg("GSSException.NAME_NOT_MN", + "The provided name was not a mechanism name."); + case OLD_TOKEN: + return getMsg("GSSException.OLD_TOKEN", + "The token's validity period has expired."); + case DUPLICATE_TOKEN: + return getMsg("GSSException.DUPLICATE_TOKEN", + "The token was a duplicate of an earlier version."); + case UNSEQ_TOKEN: + return getMsg("GSSException.UNSEQ_TOKEN", + "A later token has already been processed."); + case GAP_TOKEN: + return getMsg("GSSException.GAP_TOKEN", + "An expected per-message token was not received."); + default: return "Unknown or invalid error code."; + } + } + + /** + * Returns a string explaining the mechanism specific error code. + * <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/libjava/org/ietf/jgss/GSSManager.java b/libjava/org/ietf/jgss/GSSManager.java new file mode 100644 index 0000000..26fdd14 --- /dev/null +++ b/libjava/org/ietf/jgss/GSSManager.java @@ -0,0 +1,501 @@ +/* GSSManager.java -- manager class for the GSS-API. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* The documentation comments of this class are derived from the text + of RFC 2853: Generic Security Service API Version 2: Java Bindings. + That document is covered under the following license notice: + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it +or assist in its implementation may be prepared, copied, published and +distributed, in whole or in part, without restriction of any kind, +provided that the above copyright notice and this paragraph are +included on all such copies and derivative works. However, this +document itself may not be modified in any way, such as by removing +the copyright notice or references to the Internet Society or other +Internet organizations, except as needed for the purpose of developing +Internet standards in which case the procedures for copyrights defined +in the Internet Standards process must be followed, or as required to +translate it into languages other than English. + +The limited permissions granted above are perpetual and will not be +revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on an +"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN +WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ + + +package org.ietf.jgss; + +import java.security.Provider; +import java.security.Security; + +/** + * <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/libjava/org/ietf/jgss/GSSName.java b/libjava/org/ietf/jgss/GSSName.java new file mode 100644 index 0000000..fd158a9 --- /dev/null +++ b/libjava/org/ietf/jgss/GSSName.java @@ -0,0 +1,269 @@ +/* GSSName.java -- a name interface for GSS. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* The documentation comments of this class are derived from the text + of RFC 2853: Generic Security Service API Version 2: Java Bindings. + That document is covered under the following license notice: + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it +or assist in its implementation may be prepared, copied, published and +distributed, in whole or in part, without restriction of any kind, +provided that the above copyright notice and this paragraph are +included on all such copies and derivative works. However, this +document itself may not be modified in any way, such as by removing +the copyright notice or references to the Internet Society or other +Internet organizations, except as needed for the purpose of developing +Internet standards in which case the procedures for copyrights defined +in the Internet Standards process must be followed, or as required to +translate it into languages other than English. + +The limited permissions granted above are perpetual and will not be +revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on an +"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN +WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ + + +package org.ietf.jgss; + +/** + * <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/libjava/org/ietf/jgss/MessageProp.java b/libjava/org/ietf/jgss/MessageProp.java new file mode 100644 index 0000000..a3fd22e --- /dev/null +++ b/libjava/org/ietf/jgss/MessageProp.java @@ -0,0 +1,273 @@ +/* MessageProp.java -- GSS-API message property. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* The documentation comments of this class are derived from the text + of RFC 2853: Generic Security Service API Version 2: Java Bindings. + That document is covered under the following license notice: + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it +or assist in its implementation may be prepared, copied, published and +distributed, in whole or in part, without restriction of any kind, +provided that the above copyright notice and this paragraph are +included on all such copies and derivative works. However, this +document itself may not be modified in any way, such as by removing +the copyright notice or references to the Internet Society or other +Internet organizations, except as needed for the purpose of developing +Internet standards in which case the procedures for copyrights defined +in the Internet Standards process must be followed, or as required to +translate it into languages other than English. + +The limited permissions granted above are perpetual and will not be +revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on an +"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN +WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ + + +package org.ietf.jgss; + +/** + * <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/libjava/org/ietf/jgss/MessagesBundle.properties b/libjava/org/ietf/jgss/MessagesBundle.properties new file mode 100644 index 0000000..af8247c --- /dev/null +++ b/libjava/org/ietf/jgss/MessagesBundle.properties @@ -0,0 +1,60 @@ +# MessagesBundle.properties -- English GSS messages. +# Copyright (C) 2004 Free Software Foundation, Inc. +# +# This file is a part of GNU Classpath. +# +# GNU Classpath is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# GNU Classpath is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Classpath; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# +# Linking this library statically or dynamically with other modules is +# making a combined work based on this library. Thus, the terms and +# conditions of the GNU General Public License cover the whole +# combination. +# +# As a special exception, the copyright holders of this library give +# you permission to link this library with independent modules to +# produce an executable, regardless of the license terms of these +# independent modules, and to copy and distribute the resulting +# executable under terms of your choice, provided that you also meet, +# for each linked independent module, the terms and conditions of the +# license of that module. An independent module is a module which is +# not derived from or based on this library. If you modify this +# library, you may extend this exception to your version of the +# library, but you are not obligated to do so. If you do not wish to +# do so, delete this exception statement from your version. + +GSSException.BAD_MECH=An unsupported mechanism was requested. +GSSException.BAD_NAME=An invalid name was supplied. +GSSException.BAD_NAMETYPE=A supplied name was of an unsupported type. +GSSException.BAD_BINDINGS=Incorrect channel bindings were supplied. +GSSException.BAD_STATUS=An invalid status code was supplied. +GSSException.BAD_MIC=A token had an invalid MIC. +GSSException.NO_CRED=No credentials were supplied, or the credentials were unavailable or inaccessible. +GSSException.NO_CONTEXT=Invalid context has been supplied. +GSSException.DEFECTIVE_TOKEN=A supplied token was invalid. +GSSException.DEFECTIVE_CREDENTIAL=A supplied credential was invalid. +GSSException.CREDENTIALS_EXPIRED=The referenced credentials have expired. +GSSException.CONTEXT_EXPIRED=The context has expired. +GSSException.FAILURE=Miscellaneous failure. +GSSException.BAD_QOP=The quality-of-protection requested could not be provided. +GSSException.UNAUTHORIZED=The operation is forbidden by local security policy. +GSSException.UNAVAILABLE=The operation or option is unavailable. +GSSException.DUPLICATE_ELEMENT=The requested credential element already exists. +GSSException.NAME_NOT_MN=The provided name was not a mechanism name. +GSSException.OLD_TOKEN=The token\'s validity period has expired. +GSSException.DUPLICATE_TOKEN=The token was a duplicate of an earlier version. +GSSException.UNSEQ_TOKEN=A later token has already been processed. +GSSException.GAP_TOKEN=An expected per-message token was not received. + diff --git a/libjava/org/ietf/jgss/Oid.java b/libjava/org/ietf/jgss/Oid.java new file mode 100644 index 0000000..a7c67a7 --- /dev/null +++ b/libjava/org/ietf/jgss/Oid.java @@ -0,0 +1,385 @@ +/* Oid.java -- Object identifier class. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* The documentation comments of this class are derived from the text + of RFC 2853: Generic Security Service API Version 2: Java Bindings. + That document is covered under the following license notice: + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it +or assist in its implementation may be prepared, copied, published and +distributed, in whole or in part, without restriction of any kind, +provided that the above copyright notice and this paragraph are +included on all such copies and derivative works. However, this +document itself may not be modified in any way, such as by removing +the copyright notice or references to the Internet Society or other +Internet organizations, except as needed for the purpose of developing +Internet standards in which case the procedures for copyrights defined +in the Internet Standards process must be followed, or as required to +translate it into languages other than English. + +The limited permissions granted above are perpetual and will not be +revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on an +"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN +WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ + + +package org.ietf.jgss; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; + +import java.math.BigInteger; + +import java.util.Arrays; +import java.util.StringTokenizer; + +/** + * <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); + } + } +} |