/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.poreid.security.pcscforjava;
/**
* Access to native PC/SC functions and definition of PC/SC constants.
* Initialization and platform specific PC/SC constants are handled in
* the platform specific superclass.
*
* @since 1.6
* @author Andreas Sterbenz
* @author Matthieu Leromain
*/
final class PCSC extends PlatformPCSC {
private PCSC() {
// no instantiation
}
/**
* Check if the PC/SC functions are available on this platform.
* @throws RuntimeException if the PC/SC functions are not available on this
* platform.
*/
static void checkAvailable() throws RuntimeException {
if (initException != null) {
throw new UnsupportedOperationException
("PC/SC not available on this platform", initException);
}
}
/**
* The SCardEstablishContext function establishes the resource manager
* context (the scope) within which database operations are performed.
* @param scope Scope of the resource manager context.<br />
* This parameter can be one of the following values.<ul>
* <li>SCARD_SCOPE_USER: Database operations are performed within the domain
* of the user.</li>
* <li>SCARD_SCOPE_SYSTEM: Database operations are performed within the
* domain of the system. The calling application must have appropriate
* access permissions for any database actions.</li></ul>
* @return Handle that identifies the resource manager context.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native long SCardEstablishContext
(int scope)
throws PCSCException;
/**
* The SCardReleaseContext function closes an established resource manager
* context, freeing any resources allocated under that context, including
* SCARDHANDLE objects and memory allocated using the SCARD_AUTOALLOCATE
* length designator.
* @param lContextId Handle that identifies the resource manager context.
* The resource manager context can be set by a previous call to
* SCardEstablishContext.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native void SCardReleaseContext
(long lContextId)
throws PCSCException;
/**
* The SCardCancel function terminates all outstanding actions within a
* specific resource manager context.<br /><br />
* The only requests that you can cancel are those that require waiting for
* external action by the smart card or user. Any such outstanding action
* requests will terminate with a status indication that the action was
* canceled. This is especially useful to force outstanding
* SCardGetStatusChange calls to terminate.
* @param lContextId Handle that identifies the resource manager context.
* The resource manager context is set by a previous call to
* SCardEstablishContext.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native void SCardCancel
(long lContextId)
throws PCSCException;
/**
* The SCardIsValidContext function determines whether a smart card context
* handle is valid.
* @param lContextId Handle that identifies the resource manager context.
* The resource manager context can be set by a previous call to
* SCardEstablishContext.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native void SCardIsValidContext
(long lContextId)
throws PCSCException;
/**
* The SCardListReaders function provides the list of readers within a set
* of named reader groups, eliminating duplicates.<br /><br />
* The caller supplies a list of reader groups, and receives the list of
* readers within the named groups. Unrecognized group names are ignored.
* This function only returns readers within the named groups that are
* currently attached to the system and available for use.
* @param contextId Handle that identifies the resource manager context.
* The resource manager context can be set by a previous call to
* SCardEstablishContext.
* @return An array of readers string names.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native String[] SCardListReaders
(long contextId)
throws PCSCException;
/**
* The SCardConnect function establishes a connection (using a specific
* resource manager context) between the calling application and a smart
* card contained by a specific reader. If no card exists in the specified
* reader, an error is returned.
* @param contextId A handle that identifies the resource manager context.
* The resource manager context is set by a previous call to
* SCardEstablishContext.
* @param readerName The name of the reader that contains the target card.
* @param shareMode A flag that indicates whether other applications may
* form connections to the card.<ul>
* <li>SCARD_SHARE_SHARED: This application is willing to share the card
* with other applications.</li>
* <li>SCARD_SHARE_EXCLUSIVE: This application is not willing to share the
* card with other applications.</li>
* <li>SCARD_SHARE_DIRECT: This application is allocating the reader for its
* private use, and will be controlling it directly. No other applications
* are allowed access to it.</li></ul>
* @param preferredProtocols A bitmask of acceptable protocols for the
* connection. Possible values may be combined with the OR operation.<ul>
* <li>SCARD_PROTOCOL_T0: T=0 is an acceptable protocol.</li>
* <li>SCARD_PROTOCOL_T1: T=1 is an acceptable protocol.</li>
* <li>0: This parameter may be zero only if dwShareMode is set to
* SCARD_SHARE_DIRECT. In this case, no protocol negotiation will be
* performed by the drivers until an IOCTL_SMARTCARD_SET_PROTOCOL control
* directive is sent with SCardControl.</li></ul>
* @return Handle that identifies the connection to the smart card in the
* designated reader.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native long SCardConnect
(long contextId, String readerName, int shareMode,
int preferredProtocols) throws PCSCException;
/**
* The SCardReconnect function reestablishes an existing connection between
* the calling application and a smart card. This function moves a card
* handle from direct access to general access, or acknowledges and clears
* an error condition that is preventing further access to the card.
* @param lCardHandle Reference value obtained from a previous call to
* SCardConnect.
* @param iShareMode Flag that indicates whether other applications may
* form connections to this card.
* <ul>
* <li>SCARD_SHARE_SHARED: This application is willing to share the card
* with other applications.</li>
* <li>SCARD_SHARE_EXCLUSIVE: This application is not willing to share the
* card with other applications.</li></ul>
* @param iPreferredProtocols A bitmask of acceptable protocols for the
* connection. Possible values may be combined with the OR operation.<ul>
* <li>SCARD_PROTOCOL_T0: T=0 is an acceptable protocol.</li>
* <li>SCARD_PROTOCOL_T1: T=1 is an acceptable protocol.</li></ul>
* @param iInitialization Type of initialization that should be performed
* on the card.<ul>
* <li>SCARD_LEAVE_CARD: Do not do anything special on reconnect.</li>
* <li>SCARD_RESET_CARD: Reset the card (Warm Reset).</li>
* <li>SCARD_UNPOWER_CARD: Power down the card and reset it (Cold Reset).
* </li></ul>
* @return The Answer To Reset smart card response.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native byte[] SCardReconnect
(long lCardHandle, int iShareMode, int iPreferredProtocols,
int iInitialization)
throws PCSCException;
/**
* The SCardTransmit function sends a service request to the smart card and
* expects to receive data back from the card.
* @param cardId A reference value returned from the SCardConnect function.
* @param protocol A bitmask of acceptable protocols for the
* connection. Possible values may be combined with the OR operation.<ul>
* <li>SCARD_PROTOCOL_T0: T=0 is an acceptable protocol.</li>
* <li>SCARD_PROTOCOL_T1: T=1 is an acceptable protocol.</li>
* <li>0: This parameter may be zero only if dwShareMode is set to
* SCARD_SHARE_DIRECT. In this case, no protocol negotiation will be
* performed by the drivers until an IOCTL_SMARTCARD_SET_PROTOCOL control
* directive is sent with SCardControl.</li></ul>
* @param buf The command to send to the smart card.
* @param ofs The offset from which the command must be sent to the smart
* card.
* @param len The length of the command.
* @return The smart card response.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native byte[] SCardTransmit
(long cardId, int protocol, byte[] buf, int ofs, int len)
throws PCSCException;
/**
* The SCardStatus function provides the current status of a smart card in
* a reader. You can call it any time after a successful call to
* SCardConnect and before a successful call to SCardDisconnect. It does
* not affect the state of the reader or reader driver.
* @param cardId Reference value returned from SCardConnect.
* @param status Current state of the smart card. This variable is in/out.
* <ul><li>SCARD_ABSENT: There is no card in the reader.</li>
* <li>SCARD_PRESENT: There is a card in the reader, but it has not been
* moved into position for use.</li>
* <li>SCARD_SWALLOWED: There is a card in the reader in position for use.
* The card is not powered.</li>
* <li>SCARD_POWERED: Power is being provided to the card, but the reader
* driver is unaware of the mode of the card.</li>
* <li>SCARD_NEGOTIABLE: The card has been reset and is awaiting PTS
* negotiation.</li>
* <li>SCARD_SPECIFIC: The card has been reset and specific communication
* protocols have been established.</li></ul>
* @return The Answer To Reset of the smart card.
* @throws PCSCException if a PC/SC exception occurs.
*/
static byte[] SCardStatus(long cardId, byte[] status) throws PCSCException
{
String[] _psReaderName = new String[1];
byte [] _pBResponse = SCardStatus(cardId, status, _psReaderName);
return _pBResponse;
}
/**
* The SCardStatus function provides the current status of a smart card in
* a reader. You can call it any time after a successful call to
* SCardConnect and before a successful call to SCardDisconnect. It does
* not affect the state of the reader or reader driver.
* @param cardId Reference value returned from SCardConnect.
* @param status Current state of the smart card. This variable is in/out.
* <ul><li>SCARD_ABSENT: There is no card in the reader.</li>
* <li>SCARD_PRESENT: There is a card in the reader, but it has not been
* moved into position for use.</li>
* <li>SCARD_SWALLOWED: There is a card in the reader in position for use.
* The card is not powered.</li>
* <li>SCARD_POWERED: Power is being provided to the card, but the reader
* driver is unaware of the mode of the card.</li>
* <li>SCARD_NEGOTIABLE: The card has been reset and is awaiting PTS
* negotiation.</li>
* <li>SCARD_SPECIFIC: The card has been reset and specific communication
* protocols have been established.</li></ul>
* @param psReaderName the names of the readers which you want to check the
* status.
* @return The Answer To Reset of the smart card.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native byte[] SCardStatus
(long cardId, byte[] status, String[] psReaderName)
throws PCSCException;
/**
* The SCardDisconnect function terminates a connection previously opened
* between the calling application and a smart card in the target reader.
* @param cardId Reference value obtained from a previous call to
* SCardConnect.
* @param disposition Action to take on the card in the connected reader on
* close. <ul>
* <li>SCARD_LEAVE_CARD: Do not do anything special.</li>
* <li>SCARD_RESET_CARD: Reset the card.</li>
* <li>SCARD_UNPOWER_CARD: Power down the card.</li>
* <li>SCARD_EJECT_CARD: Eject the card.</li></ul>
* @throws PCSCException if a PC/SC exception occurs.
*/
static native void SCardDisconnect
(long cardId, int disposition)
throws PCSCException;
/**
* The SCardGetStatusChange function blocks execution until the current
* availability of the cards in a specific set of readers changes.<br />
* <br />
* The caller supplies a list of readers to be monitored by an
* SCARD_READERSTATE array and the maximum amount of time (in milliseconds)
* that it is willing to wait for an action to occur on one of the listed
* readers. Note that SCardGetStatusChange uses the user-supplied value in
* the dwCurrentState members of the rgReaderStates SCARD_READERSTATE array
* as the definition of the current state of the readers. The function
* returns when there is a change in availability, having filled in the
* dwEventState members of rgReaderStates appropriately.
* @param contextId A handle that identifies the resource manager context.
* The resource manager context is set by a previous call to the
* SCardEstablishContext function.
* @param timeout The maximum amount of time, in milliseconds, to wait for
* an action. A value of zero causes the function to return immediately. A
* value of INFINITE causes this function never to time out.
* @param currentState Current state of the smart card. This variable is
* in/out.
* <ul><li>SCARD_ABSENT: There is no card in the reader.</li>
* <li>SCARD_PRESENT: There is a card in the reader, but it has not been
* moved into position for use.</li>
* <li>SCARD_SWALLOWED: There is a card in the reader in position for use.
* The card is not powered.</li>
* <li>SCARD_POWERED: Power is being provided to the card, but the reader
* driver is unaware of the mode of the card.</li>
* <li>SCARD_NEGOTIABLE: The card has been reset and is awaiting PTS
* negotiation.</li>
* <li>SCARD_SPECIFIC: The card has been reset and specific communication
* protocols have been established.</li></ul>
* @param readerNames the names of the readers which you want to check the
* status.
* @return dwEventState[] of the same size and order as readerNames[].
* @throws PCSCException if a PC/SC exception occurs.
*/
static native int[] SCardGetStatusChange
(long contextId, long timeout, int[] currentState,
String[] readerNames) throws PCSCException;
/**
* The SCardBeginTransaction function starts a transaction.<br /><br />
* The function waits for the completion of all other transactions before it
* begins. After the transaction starts, all other applications are blocked
* from accessing the smart card while the transaction is in progress.
* @param cardId A reference value obtained from a previous call to
* SCardConnect.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native void SCardBeginTransaction
(long cardId)
throws PCSCException;
/**
* The SCardEndTransaction function completes a previously declared
* transaction, allowing other applications to resume interactions with the
* card.
* @param cardId A reference value obtained from a previous call to
* SCardConnect.
* @param disposition Action to take on the card in the connected reader on
* close. <ul>
* <li>SCARD_LEAVE_CARD: Do not do anything special.</li>
* <li>SCARD_RESET_CARD: Reset the card.</li>
* <li>SCARD_UNPOWER_CARD: Power down the card.</li>
* <li>SCARD_EJECT_CARD: Eject the card.</li></ul>
* @throws PCSCException if a PC/SC exception occurs.
*/
static native void SCardEndTransaction
(long cardId, int disposition)
throws PCSCException;
/**
* The SCardControl function gives you direct control of the reader. You
* can call it any time after a successful call to SCardConnect and before
* a successful call to SCardDisconnect. The effect on the state of the
* reader depends on the control code.
* @param cardId Reference value returned from SCardConnect.
* @param controlCode Control code for the operation. This value identifies
* the specific operation to be performed.
* @param sendBuffer Buffer that contains the data required to perform the
* operation. This parameter can be NULL if the dwControlCode parameter
* specifies an operation that does not require input data.
* @return Response of the reader.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native byte[] SCardControl
(long cardId, int controlCode, byte[] sendBuffer)
throws PCSCException;
/**
* The SCardGetAttrib function retrieves the current reader attributes for
* the given handle. It does not affect the state of the reader, driver,
* or card.
* @param lCardId Reference value returned from SCardConnect.
* @param iAttribute Identifier for the attribute to get. The following
* table lists possible values for dwAttrId. These values are read-only.
* Note that vendors may not support all attributes.
* <li>{@link SCARD_ATTR_ATR_STRING SCARD_ATTR_ATR_STRING}: Answer to reset
* (ATR) string.</li>
* <li>{@link SCARD_ATTR_CHANNEL_ID SCARD_ATTR_CHANNEL_ID}:
* unsigned long encoded as 0xDDDDCCCC, where DDDD = data channel type
* and CCCC = channel number:<br />
* The following encodings are defined for DDDD:<br /><ul>
* <li>0x01 serial I/O; CCCC is a port number.</li>
* <li>0x02 parallel I/O; CCCC is a port number.</li>
* <li>0x04 PS/2 keyboard port; CCCC is zero.</li>
* <li>0x08 SCSI; CCCC is SCSI ID number.</li>
* <li>0x10 IDE; CCCC is device number.</li>
* <li>0x20 USB; CCCC is device number.</li>
* <li>0xFy vendor-defined interface with y in the range zero through 15;
* CCCC is vendor defined.</li></ul>
* <li>{@link SCARD_ATTR_CHARACTERISTICS SCARD_ATTR_CHARACTERISTICS}:
* unsigned long indicating which mechanical characteristics are supported.
* <br />If zero, no special characteristics are supported.<br />
* Note that multiple bits can be set:<br /><ul>
* <li>0x00000001 Card swallowing mechanism.</li>
* <li>0x00000002 Card ejection mechanism.</li>
* <li>0x00000004 Card capture mechanism.</li>
* <li>All other values are reserved for future use (RFU).</li></ul>
* <li>{@link SCARD_ATTR_CURRENT_BWT SCARD_ATTR_CURRENT_BWT}: Current block
* waiting time.
* <li>{@link SCARD_ATTR_CURRENT_CLK SCARD_ATTR_CURRENT_CLK}: Current clock
* rate, in kHz.
* <li>{@link SCARD_ATTR_CURRENT_CWT SCARD_ATTR_CURRENT_CWT}: Current
* character waiting time.
* <li>{@link SCARD_ATTR_CURRENT_D SCARD_ATTR_CURRENT_D}: Bit rate conversion
* factor.
* <li>{@link SCARD_ATTR_CURRENT_EBC_ENCODING
* SCARD_ATTR_CURRENT_EBC_ENCODING}:
* Current error block control encoding.<br /><ul>
* <li>0 = Longitudinal Redundancy Check (LRC).</li>
* <li>1 = Cyclical Redundancy Check (CRC).</li></ul>
* <li>{@link SCARD_ATTR_CURRENT_F SCARD_ATTR_CURRENT_F}: Clock conversion
* factor.
* <li>{@link SCARD_ATTR_CURRENT_IFSC SCARD_ATTR_CURRENT_IFSC}: Current byte
* size for information field size card.
* <li>{@link SCARD_ATTR_CURRENT_IFSD SCARD_ATTR_CURRENT_IFSD}: Current byte
* size for information field size device.
* <li>{@link SCARD_ATTR_CURRENT_N SCARD_ATTR_CURRENT_N}: Current guard time.
* <li>{@link SCARD_ATTR_CURRENT_PROTOCOL_TYPE
* SCARD_ATTR_CURRENT_PROTOCOL_TYPE}:
* unsigned long encoded as 0x0rrrpppp where rrr is RFU and should be
* 0x000.<br />
* pppp encodes the current protocol type. Whichever bit has been set
* indicates which ISO protocol is currently in use. (For example, if bit
* zero is set, T=0 protocol is in effect.)
* <li>{@link SCARD_ATTR_CURRENT_W SCARD_ATTR_CURRENT_W}: Current work
* waiting time.
* <li>{@link SCARD_ATTR_DEFAULT_CLK SCARD_ATTR_DEFAULT_CLK}: Default clock
* rate, in kHz.
* <li>{@link SCARD_ATTR_DEFAULT_DATA_RATE SCARD_ATTR_DEFAULT_DATA_RATE}:
* Default data rate, in bps.
* <li>{@link SCARD_ATTR_DEVICE_FRIENDLY_NAME
* SCARD_ATTR_DEVICE_FRIENDLY_NAME}: Reader's display name.
* <li>{@link SCARD_ATTR_DEVICE_IN_USE SCARD_ATTR_DEVICE_IN_USE}: Reserved
* for future use.
* <li>{@link SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME}:
* Reader's system name.
* <li>{@link SCARD_ATTR_DEVICE_UNIT SCARD_ATTR_DEVICE_UNIT}:
* Instance of this vendor's reader attached to the computer. The first
* instance will be device unit 0, the next will be unit 1 (if it is the
* same brand of reader) and so on.<br />
* Two different brands of readers will both have zero for this value.
* <li>{@link SCARD_ATTR_ICC_INTERFACE_STATUS
* SCARD_ATTR_ICC_INTERFACE_STATUS}: Single byte. Zero if smart card
* electrical contact is not active; nonzero if contact is active.
* <li>{@link SCARD_ATTR_ICC_PRESENCE SCARD_ATTR_ICC_PRESENCE}:
* Single byte indicating smart card presence:<br /><ul>
* <li>0 = not present.</li>
* <li>1 = card present but not swallowed (applies only if reader supports
* smart card swallowing).</li>
* <li>2 = card present (and swallowed if reader supports smart card
* swallowing).</li>
* <li>4 = card confiscated.</li></ul>
* <li>{@link SCARD_ATTR_ICC_TYPE_PER_ATR SCARD_ATTR_ICC_TYPE_PER_ATR}:
* Single byte indicating smart card type:<br /><ul>
* <li>0 = unknown type.</li>
* <li>1 = 7816 Asynchronous.</li>
* <li>2 = 7816 Synchronous.</li>
* <li>Other values RFU.</li></ul>
* <li>{@link SCARD_ATTR_MAX_CLK SCARD_ATTR_MAX_CLK}: Maximum clock rate, in
* kHz.
* <li>{@link SCARD_ATTR_MAX_DATA_RATE SCARD_ATTR_MAX_DATA_RATE}: Maximum
* data rate, in bps.
* <li>{@link SCARD_ATTR_MAX_IFSD SCARD_ATTR_MAX_IFSD}: Maximum bytes for
* information file size device.
* <li>{@link SCARD_ATTR_POWER_MGMT_SUPPORT SCARD_ATTR_POWER_MGMT_SUPPORT}:
* Zero if device does not support power down while smart card is inserted.
* <br />Nonzero otherwise.
* <li>{@link SCARD_ATTR_PROTOCOL_TYPES SCARD_ATTR_PROTOCOL_TYPES}:
* unsigned long encoded as 0x0rrrpppp where rrr is RFU and should be 0x000.
* <br />pppp encodes the supported protocol types. A '1' in a given bit
* position indicates support for the associated ISO protocol, so if bits
* zero and one are set, both T=0 and T=1 protocols are supported.
* <li>{@link SCARD_ATTR_VENDOR_IFD_SERIAL_NO
* SCARD_ATTR_VENDOR_IFD_SERIAL_NO}: Vendor-supplied interface device serial
* number.
* <li>{@link SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VENDOR_IFD_TYPE}:
* Vendor-supplied interface device type (model designation of reader).
* <li>{@link SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_VENDOR_IFD_VERSION}:
* Vendor-supplied interface device version (DWORD in the form 0xMMmmbbbb
* where MM = major version, mm = minor version, and bbbb = build number).
* <li>{@link SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VENDOR_NAME}: Vendor name.
* </ul>
* @return the current reader attribute.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native byte[] SCardGetAttrib
(long lCardId, int iAttribute)
throws PCSCException;
/**
* The SCardSetAttrib function sets the given reader attribute for the
* given handle. It does not affect the state of the reader, reader driver,
* or smart card. Not all attributes are supported by all readers (nor can
* they be set at all times) as many of the attributes are under direct
* control of the transport protocol.
* @param lCardId Reference value returned from SCardConnect.
* @param iAttribute Identifier for the attribute to set. The values are
* write-only. Note that vendors may not support all attributes.
* @param pBCommand Pointer to a buffer that supplies the attribute whose
* ID is supplied in dwAttrId.
* @throws PCSCException if a PC/SC exception occurs.
*/
static native void SCardSetAttrib
(long lCardId, int iAttribute, byte[] pBCommand)
throws PCSCException;
// Infinite timeout
final static int TIMEOUT_INFINITE = 0xffffffff;
private final static char[] hexDigits = "0123456789abcdef".toCharArray();
/**
* Returns string description of byte array.
* @param b the byte array.
* @return string description of byte array.
*/
public static String toString(byte[] b) {
StringBuilder sb = new StringBuilder(b.length * 3);
for (int i = 0; i < b.length; i++) {
int k = b[i] & 0xff;
if (i != 0) {
sb.append(':');
}
sb.append(hexDigits[k >>> 4]);
sb.append(hexDigits[k & 0xf]);
}
return sb.toString();
}
}