/***********************************************************
* $Id: PKCS11Slot.java 62 2007-02-15 08:14:53Z wolfgang.glas $
*
* PKCS11 provider of the OpenSC project http://www.opensc-project.org
*
* Copyright (C) 2006 ev-i Informationstechnologie GmbH
*
* Created: Jul 16, 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 java.util.ArrayList;
import java.util.List;
import javax.security.auth.DestroyFailedException;
import org.opensc.pkcs11.PKCS11Provider;
import org.opensc.util.DestroyableHolder;
import de.kp.logging.Log;
import de.kp.logging.LogFactory;
public class PKCS11Slot extends DestroyableHolder
{
static private final Log log = LogFactory.getLog(PKCS11Slot.class);
/**
* The ID of the token.
*/
private long id;
/**
* The C handle of the provider.
*/
private long pvh;
/**
* The C handle of the slot.
*/
private long handle;
private native long initSlotNative(long _pvh, long _id) throws PKCS11Exception;
private native void destroySlotNative(long _pvh, long _handle) throws DestroyFailedException;
/**
* This contructor constructs an instance of an individual slot.
* The slots a usually label starting with an Id of 0 and onwards.
* So, if you have just one device attached to your computer you
* should usually done by calling new PKCS11Slot(provider,0).
*
* @param id The Id of the slot.
* @throws PKCS11Exception Upon errors when retrieving the slot information.
*/
public PKCS11Slot(PKCS11Provider provider, long id) throws PKCS11Exception
{
super(provider);
this.id = id;
this.pvh = provider.getPkcs11ModuleHandle();
this.handle = initSlotNative(this.pvh,id);
}
private static native long[] enumerateSlotsNative(long pvh) throws PKCS11Exception;
/**
* Enumeraate all available slots of a given PKCS11 provider.
*
* @param provider The PKCS11 provider to retrieve the slots for.
* @return A list of all available slots.
* @throws PKCS11Exception Upon errors when retrieving the slot information.
*/
public static List<PKCS11Slot> enumerateSlots(PKCS11Provider provider) throws PKCS11Exception
{
long[] ids = enumerateSlotsNative(provider.getPkcs11ModuleHandle());
List<PKCS11Slot> ret = new ArrayList<PKCS11Slot> (ids.length);
for (int i = 0; i < ids.length; i++)
{
ret.add(new PKCS11Slot(provider, ids[i]));
}
return ret;
}
private static native long waitForSlotNative(long pvh) throws PKCS11Exception;
/**
* Enumerate all available slots of a given PKCS11 provider.
*
* @param provider The PKCS11 provider to retrieve the slots for.
* @return A list of all available slots.
* @throws PKCS11Exception Upon errors when retrieving the slot information.
*/
public static PKCS11Slot waitForSlot(PKCS11Provider provider)
throws PKCS11Exception
{
long id = -1;
try
{
id = waitForSlotNative(provider.getPkcs11ModuleHandle());
} catch (PKCS11Exception e)
{
if (e.getErrorCode() == PKCS11Exception.CKR_FUNCTION_NOT_SUPPORTED)
try
{
PKCS11Slot ret = null;
do
{
Thread.sleep(1000);
List<PKCS11Slot> slots = enumerateSlots(provider);
for (PKCS11Slot slot : slots)
{
if (ret == null && slot.isTokenPresent())
ret = slot;
else
try
{
slot.destroy();
} catch (DestroyFailedException e1)
{
log.warn("destroy error while waiting for slot:",
e1);
}
}
} while (ret == null);
return ret;
} catch (InterruptedException e1)
{
throw new PKCS11Exception(
PKCS11Exception.CKR_FUNCTION_CANCELED,
"The operation has been interrupted.");
}
else
{
throw e;
}
}
return new PKCS11Slot(provider, id);
}
private native boolean isTokenPresentNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return Whether a token is present in this slot.
*/
public boolean isTokenPresent() throws PKCS11Exception
{
return isTokenPresentNative(this.pvh,this.handle);
}
private native boolean isRemovableDeviceNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return Whether a token is present in this slot.
*/
public boolean isRemovableDevice() throws PKCS11Exception
{
return isRemovableDeviceNative(this.pvh,this.handle);
}
private native boolean isHardwareDeviceNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return Whether a token is present in this slot.
*/
public boolean isHardwareDevice() throws PKCS11Exception
{
return isHardwareDeviceNative(this.pvh,this.handle);
}
private native byte[] getManufacturerNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The manufacturer of the slot.
*/
public String getManufacturer() throws PKCS11Exception
{
try
{
return new String(getManufacturerNative(this.pvh,this.handle),"UTF-8");
} catch (UnsupportedEncodingException e)
{
return null;
}
}
private native byte[] getDescriptionNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return A description of the slot.
*/
public String getDescription() throws PKCS11Exception
{
try
{
return new String(getDescriptionNative(this.pvh,this.handle),"UTF-8");
} catch (UnsupportedEncodingException e)
{
return null;
}
}
private native double getHardwareVersionNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The hardware verion of the slot.
*/
public double getHardwareVersion() throws PKCS11Exception
{
return getHardwareVersionNative(this.pvh,this.handle);
}
private native double getFirmwareVersionNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The Firmware verion of the slot.
*/
public double getFirmwareVersion() throws PKCS11Exception
{
return getFirmwareVersionNative(this.pvh,this.handle);
}
private native PKCS11Mechanism[] getMechanismsNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return A list of mechanisms supported by this slot.
* @throws PKCS11Exception
*/
public PKCS11Mechanism[] getMechanisms() throws PKCS11Exception
{
return getMechanismsNative(this.pvh,this.handle);
}
private native byte[] getTokenLabelNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The label of the token.
* @throws PKCS11Exception When no token is in the slot or another
* error of the underlying PKCS#11 engine occurrs.
*
* @see PKCS11Slot#isTokenPresent()
*/
public String getTokenLabel() throws PKCS11Exception
{
try
{
return new String(getTokenLabelNative(this.pvh,this.handle),"UTF-8");
} catch (UnsupportedEncodingException e)
{
return null;
}
}
private native byte[] getTokenManufacturerNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The manufacturer of the token.
* @throws PKCS11Exception When no token is in the slot or another
* error of the underlying PKCS#11 engine occurrs.
*
* @see PKCS11Slot#isTokenPresent()
*/
public String getTokenManufacturer() throws PKCS11Exception
{
try
{
return new String(getTokenManufacturerNative(this.pvh,this.handle),"UTF-8");
} catch (UnsupportedEncodingException e)
{
return null;
}
}
private native byte[] getTokenModelNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The model of the token.
* @throws PKCS11Exception When no token is in the slot or another
* error of the underlying PKCS#11 engine occurrs.
*
* @see PKCS11Slot#isTokenPresent()
*/
public String getTokenModel() throws PKCS11Exception
{
try
{
return new String(getTokenModelNative(this.pvh,this.handle),"UTF-8");
} catch (UnsupportedEncodingException e)
{
return null;
}
}
private native byte[] getTokenSerialNumberNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The serial number of the token.
* @throws PKCS11Exception When no token is in the slot or another
* error of the underlying PKCS#11 engine occurrs.
*
* @see PKCS11Slot#isTokenPresent()
*/
public String getTokenSerialNumber() throws PKCS11Exception
{
try
{
return new String(getTokenSerialNumberNative(this.pvh,this.handle),"UTF-8");
} catch (UnsupportedEncodingException e)
{
return null;
}
}
private native int getTokenMinPinLenNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The minimal PIN length of the token.
* @throws PKCS11Exception When no token is in the slot or another
* error of the underlying PKCS#11 engine occurrs.
*
* @see PKCS11Slot#isTokenPresent()
*/
public int getTokenMinPinLen() throws PKCS11Exception
{
return getTokenMinPinLenNative(this.pvh,this.handle);
}
private native int getTokenMaxPinLenNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* @return The maximal PIN length of the token.
* @throws PKCS11Exception When no token is in the slot or another
* error of the underlying PKCS#11 engine occurrs.
*
* @see PKCS11Slot#isTokenPresent()
*/
public int getTokenMaxPinLen() throws PKCS11Exception
{
return getTokenMaxPinLenNative(this.pvh,this.handle);
}
private native boolean hasTokenProtectedAuthPathNative(long _pvh, long _handle) throws PKCS11Exception;
/**
* Checks, if the token has an protected authentication path via a PINpad
* or another hardware authentication method.
*
* @return Whether the token has a protected authentication path.
* If <code>true</code>, PIN parameters passed to the login
* functions of an associated session may be null.
*
* @throws PKCS11Exception When no token is in the slot or another
* error of the underlying PKCS#11 engine occurrs.
*
* @see PKCS11Slot#isTokenPresent()
* @see PKCS11Session#loginUser(char[])
* @see PKCS11Session#loginSO(char[])
*/
public boolean hasTokenProtectedAuthPath() throws PKCS11Exception
{
return hasTokenProtectedAuthPathNative(this.pvh,this.handle);
}
/**
* @return Returns the id of this slot.
*/
public long getId()
{
return this.id;
}
/* (non-Javadoc)
* @see org.opensc.pkcs11.util.DestroyableChild#destroy()
*/
@Override
public void destroy() throws DestroyFailedException
{
super.destroy();
if (this.handle != 0)
{
destroySlotNative(this.pvh,this.handle);
this.handle = 0;
}
}
/**
* @return Returns the C handle of the underlying provider.
*/
protected long getPvh()
{
return this.pvh;
}
/**
* @return Returns the C handle of the slot.
*/
protected long getHandle()
{
return this.handle;
}
}