/* * Copyright 1999-2010 University of Chicago * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * * See the License for the specific language governing permissions and limitations under the License. */ package org.globus.gsi.gssapi; import org.globus.util.Util; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSName; import org.ietf.jgss.Oid; import org.gridforum.jgss.ExtendedGSSCredential; import java.security.cert.X509Certificate; import java.security.PrivateKey; import java.io.ByteArrayOutputStream; import java.io.Serializable; import java.io.IOException; import java.io.File; import java.io.FileOutputStream; import org.globus.gsi.X509Credential; import java.security.cert.CertificateEncodingException; import org.globus.gsi.CredentialException; /** * An implementation of <code>GlobusGSSCredential</code>. */ public class GlobusGSSCredentialImpl implements ExtendedGSSCredential, Serializable { private static final long serialVersionUID = 1L; private int usage = 0; private X509Credential cred; private GSSName name; /** * Creates anonymous credential. */ public GlobusGSSCredentialImpl() { this.cred = null; this.name = new GlobusGSSName(); } /** * Creates regular credential from specified * X509Credential object. * * @param cred the credential * @param usage credential usage */ public GlobusGSSCredentialImpl(X509Credential cred, int usage) throws GSSException { if (cred == null) { throw new IllegalArgumentException("cred == null"); } this.cred = cred; this.usage = usage; this.name = new GlobusGSSName(cred.getIdentity()); } @Override public int hashCode() { if (this.cred == null) { return this.usage; } else { return this.cred.hashCode() + this.usage; } } @Override public boolean equals(Object obj) { if (obj instanceof GlobusGSSCredentialImpl) { GlobusGSSCredentialImpl other = (GlobusGSSCredentialImpl)obj; return other.usage == this.usage && (other.cred == this.cred || this.cred != null && this.cred.equals(other.cred)); } return false; } public void dispose() throws GSSException { this.cred = null; } public GSSName getName() throws GSSException { return this.name; } public GSSName getName(Oid mech) throws GSSException { GlobusGSSManagerImpl.checkMechanism(mech); return this.name; } /** * Currently not implemented. */ public void add(GSSName aName, int initLifetime, int acceptLifetime, Oid mech, int usage) throws GSSException { // currently we are not supporting multiple mechanism // credentials throw new GSSException(GSSException.UNAVAILABLE); } public int getUsage() throws GSSException { return usage; } public int getUsage(Oid mech) throws GSSException { GlobusGSSManagerImpl.checkMechanism(mech); return this.usage; } public int getRemainingLifetime() throws GSSException { return (this.cred == null) ? -1 : (int)this.cred.getTimeLeft(); } public int getRemainingInitLifetime(Oid mech) throws GSSException { GlobusGSSManagerImpl.checkMechanism(mech); if (this.usage == INITIATE_ONLY || this.usage == INITIATE_AND_ACCEPT) { return getRemainingLifetime(); } else { throw new GSSException(GSSException.FAILURE); } } public int getRemainingAcceptLifetime(Oid mech) throws GSSException { GlobusGSSManagerImpl.checkMechanism(mech); if (this.usage == ACCEPT_ONLY || this.usage == INITIATE_AND_ACCEPT) { return getRemainingLifetime(); } else { throw new GSSException(GSSException.FAILURE); } } public Oid[] getMechs() throws GSSException { return GlobusGSSManagerImpl.MECHS; } public byte[] export(int option) throws GSSException { return export(option, null); } public byte[] export(int option, Oid mech) throws GSSException { GlobusGSSManagerImpl.checkMechanism(mech); if (this.cred == null) { throw new GlobusGSSException(GSSException.FAILURE, GlobusGSSException.CREDENTIAL_ERROR, "anonCred00"); } switch (option) { case IMPEXP_OPAQUE: ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { this.cred.save(bout); } catch (IOException e) { throw new GlobusGSSException(GSSException.FAILURE, e); } catch (CertificateEncodingException e) { throw new GlobusGSSException(GSSException.FAILURE, e); } return bout.toByteArray(); case IMPEXP_MECH_SPECIFIC: File file = null; FileOutputStream fout = null; try { file = File.createTempFile("x509up_", ".tmp"); Util.setOwnerAccessOnly(file.getAbsolutePath()); fout = new FileOutputStream(file); this.cred.save(fout); } catch(IOException e) { throw new GlobusGSSException(GSSException.FAILURE, e); } catch (CertificateEncodingException e) { throw new GlobusGSSException(GSSException.FAILURE, e); } finally { if (fout != null) { try { fout.close(); } catch (Exception e) {} } } String handle = "X509_USER_PROXY=" + file.getAbsolutePath(); return handle.getBytes(); default: throw new GlobusGSSException(GSSException.FAILURE, GlobusGSSException.BAD_ARGUMENT, "unknownOption", new Object[] {new Integer(option)}); } } /** * Retrieves arbitrary data about this credential. * Currently supported oid: <UL> * <LI> * {@link GSSConstants#X509_CERT_CHAIN GSSConstants.X509_CERT_CHAIN} * returns certificate chain of this credential * (<code>X509Certificate[]</code>). * </LI> * </UL> * * @param oid the oid of the information desired. * @return the information desired. Might be null. * @exception GSSException containing the following major error codes: * <code>GSSException.FAILURE</code> */ public Object inquireByOid(Oid oid) throws GSSException { if (oid == null) { throw new GlobusGSSException(GSSException.FAILURE, GlobusGSSException.BAD_ARGUMENT, "nullOption"); } if (oid.equals(GSSConstants.X509_CERT_CHAIN)) { return (this.cred == null) ? null : this.cred.getCertificateChain(); } return null; } /** * Returns actual X509Credential object represented * by this credential (if any). * * @return The credential object. Might be null if * this is an anonymous credential. */ public X509Credential getX509Credential() { return this.cred; } /** * Returns the private key of this credential (if any). * * @return The private key. Might be null if this * is an anonymous credential. */ public PrivateKey getPrivateKey() throws GSSException { try { return (this.cred == null) ? null : this.cred.getPrivateKey(); } catch (CredentialException e) { throw new GlobusGSSException(GSSException.FAILURE, e); } } /** * Returns certificate chain of this credential (if any). * * @return The certificate chain. Might be null if this * is an anonymous credential. */ public X509Certificate [] getCertificateChain() { return (this.cred == null) ? null : this.cred.getCertificateChain(); } }