/***********************************************************
* $Id: PKCS11Object.java 57 2007-02-14 16:02:54Z wolfgang.glas $
*
* PKCS11 provider of the OpenSC project http://www.opensc-project.org
*
* Copyright (C) 2002-2006 ev-i Informationstechnologie GmbH
*
* Created: Jul 17, 2006
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
***********************************************************/
package org.opensc.pkcs11.wrap;
import java.io.UnsupportedEncodingException;
import javax.security.auth.DestroyFailedException;
import org.opensc.pkcs11.PKCS11Provider;
import org.opensc.util.DestroyableChild;
import org.opensc.util.PKCS11Id;
/**
* @author wglas
*
* This class manages Objects like certificates or keys
* stored on a PKCS11 device in a specific slot.
*/
public class PKCS11Object extends DestroyableChild implements PKCS11SessionChild
{
/**
* The C handle of the provider.
*/
protected long pvh;
/**
* The C handle of the slot.
*/
protected long shandle;
/**
* The C handle of the session.
*/
protected long hsession;
/**
* The C handle of the object.
*/
protected long handle;
/**
* The Id of the object, i.e. the CKA_ID attribute value.
*/
private PKCS11Id id;
/**
* The Id of the object, i.e. the CKA_ID attribute value.
*/
private String label;
/*
* PKCS11 Class constants used for enumeration imported from pkcs11t.h
*/
static public final int CKO_CERTIFICATE = 0x00000001;
static public final int CKO_PUBLIC_KEY = 0x00000002;
static public final int CKO_PRIVATE_KEY = 0x00000003;
static public final int CKO_SECRET_KEY = 0x00000004;
/* internal native interface */
private static native long[] enumObjectsNative(long pvh, long slot_handle, long hsession, PKCS11Attribute[] attrs) throws PKCS11Exception;
private static native byte[] getAttributeNative(long pvh, long slot_handle, long hsession, long handle, int att) throws PKCS11Exception;
private static native int getULongAttributeNative(long pvh, long slot_handle, long hsession, long handle, int att) throws PKCS11Exception;
private static native boolean getBooleanAttributeNative(long pvh, long slot_handle, long hsession, long handle, int att) throws PKCS11Exception;
private static native PKCS11Mechanism[] getAllowedMechanismsNative(long pvh, long slot_handle, long hsession, long handle) throws PKCS11Exception;
private static native long createObjectNative(long pvh, long slot_handle, long hsession, PKCS11Attribute[] attrs) throws PKCS11Exception;
/**
* Just a small wrapper around the native function.
* @param att The attribute type to receive.
* @return The raw value of the attribute.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
protected byte[] getRawAttribute(int att) throws PKCS11Exception
{
return getAttributeNative(this.pvh,this.shandle,this.hsession,this.handle,att);
}
/**
* Just a small wrapper around the native function.
* @param att The attribute type to receive.
* @return The 4-byte integer value of the attribute.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
protected int getULongAttribute(int att) throws PKCS11Exception
{
return getULongAttributeNative(this.pvh,this.shandle,this.hsession,this.handle,att);
}
/**
* Just a small wrapper around the native function.
* @param att The attribute type to receive.
* @return The 4-byte integer value of the attribute.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
protected static int getULongAttribute(PKCS11Session session, long handle, int att) throws PKCS11Exception
{
return getULongAttributeNative(session.getPvh(),session.getSlotHandle(),session.getHandle(),handle,att);
}
/**
* Just a small wrapper around the native function.
* @param att The attribute type to receive.
* @return The boolean value of the attribute.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
protected boolean getBooleanAttribute(int att) throws PKCS11Exception
{
return getBooleanAttributeNative(this.pvh,this.shandle,this.hsession,this.handle,att);
}
/**
* Just a small wrapper around the native function.
* @param att The attribute type to receive.
* @return The 4-byte integer value of the attribute.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
protected static boolean getBooleanAttribute(PKCS11Session session, long handle, int att) throws PKCS11Exception
{
return getBooleanAttributeNative(session.getPvh(),session.getSlotHandle(),session.getHandle(),handle,att);
}
/**
* Just a small wrapper around the native function.
* @param session The session for which to enumerate the objects.
* @param pkcs11_cls The object class to be seeked.
* Should be one of the CKO_* constants
* @return The object handles of the retrieved objects,
* which have to be passed to the constructor.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
protected static long[] enumRawObjects(PKCS11Session session, int pkcs11_cls) throws PKCS11Exception
{
PKCS11Attribute attrs[] = new PKCS11Attribute[1];
attrs[0] = new PKCS11Attribute(PKCS11Attribute.CKA_CLASS,pkcs11_cls);
return enumObjectsNative(session.getPvh(),session.getSlotHandle(),session.getHandle(),
attrs);
}
/**
* Just a small wrapper around the native function.
* @param session The session for which to find an object.
* @param pkcs11_cls The object class to be seeked.
* Should be one of the CKO_* constants.
* @param id The object id to be searched.
* @return The object handles of the retrieved objects,
* which have to be passed to the constructor.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
protected static long findRawObject(PKCS11Session session, int pkcs11_cls, PKCS11Id id) throws PKCS11Exception
{
PKCS11Attribute attrs[] = new PKCS11Attribute[2];
attrs[0] = new PKCS11Attribute(PKCS11Attribute.CKA_CLASS,pkcs11_cls);
attrs[1] = new PKCS11Attribute(PKCS11Attribute.CKA_ID,id);
long[] handles = enumObjectsNative(session.getPvh(),session.getSlotHandle(),session.getHandle(),
attrs);
if (handles == null || handles.length < 1)
throw new PKCS11Exception("The requested object with id "+id+" of class "+pkcs11_cls+" was not found.");
if (handles.length > 1)
throw new PKCS11Exception("There are more than one objects with id "+id+" of class "+pkcs11_cls+".");
return handles[0];
}
/**
* Just a small wrapper around the native function.
* @param session The session in which to create the new objects.
* @param attrs The attributes of the new object to save.
* @return The object handle, which may be used by subclasses in order to construct
* a new specialized object like PKCS11Certificate.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
protected static long createObject(PKCS11Session session, PKCS11Attribute[] attrs) throws PKCS11Exception
{
return createObjectNative(session.getPvh(),session.getSlotHandle(),session.getHandle(), attrs);
}
/**
* Protected contructor used by subclasses.
*/
protected PKCS11Object(PKCS11Session session, long handle) throws PKCS11Exception
{
super(session);
this.pvh = session.getPvh();
this.shandle = session.getSlotHandle();
this.hsession = session.getHandle();
this.handle = handle;
try
{
this.id = new PKCS11Id(getRawAttribute(PKCS11Attribute.CKA_ID));
byte[] utf8_label = getRawAttribute(PKCS11Attribute.CKA_LABEL);
this.label = new String(utf8_label,"UTF-8");
} catch (UnsupportedEncodingException e)
{
throw new PKCS11Exception("Invalid encoding:",e);
}
}
/**
* Just a small wrapper atround the native function.
* @return The allowed mechanism for this object.
* @throws PKCS11Exception Upon errors of the underlying PKCS#11 module.
*/
public PKCS11Mechanism[] getAllowedMechanisms() throws PKCS11Exception
{
return getAllowedMechanismsNative(this.pvh,this.shandle,this.hsession,this.handle);
}
/**
* @return The Id of this object.
*/
public PKCS11Id getId()
{
return this.id;
}
/**
* @return The label of this object.
*/
public String getLabel()
{
return this.label;
}
/**
* @return The underlying PKCS11 security provider.
* This function throws a runtime exception, if destroy()
* has been called before.
*/
public PKCS11Provider getProvider()
{
DestroyableChild session = (DestroyableChild)getParent();
DestroyableChild slot = (DestroyableChild)session.getParent();
return (PKCS11Provider)slot.getParent();
}
/* (non-Javadoc)
* @see org.opensc.pkcs11.wrap.PKCS11SessionChild#getPvh()
*/
public long getPvh()
{
return this.pvh;
}
/* (non-Javadoc)
* @see org.opensc.pkcs11.wrap.PKCS11SessionChild#getSlotHandle()
*/
public long getSlotHandle()
{
return this.shandle;
}
/* (non-Javadoc)
* @see org.opensc.pkcs11.wrap.PKCS11SessionChild#getSessionHandle()
*/
public long getSessionHandle()
{
return this.hsession;
}
/* (non-Javadoc)
* @see org.opensc.pkcs11.wrap.PKCS11SessionChild#getHandle()
*/
public long getHandle()
{
return this.handle;
}
/* (non-Javadoc)
* @see org.opensc.util.DestroyableChild#destroy()
*/
@Override
public void destroy() throws DestroyFailedException
{
// just invalidate the handles.
this.pvh = 0;
this.shandle = 0;
this.hsession = 0;
this.handle = 0;
super.destroy();
}
}