Use the PPDU features provided by the PCR
EWC provides functions to verify and change the card holder's PIN using the PPDU mechanism (see the Overview page for more details).
Once EWC is initialized after a call to the "init" function, your page is able to react on smart card insertion to trigger an operation (see the "initialization" and "detection" pages for more details).
The PPDU function is not exposed by the top level EWC API. When a smart card is inserted into the reader and validated as usuable, a "Connection" object is automatically created by the EWC library. The "Connection" object exposes all functions for PPDU operations. The first step is to get the Connection object. A reference to this object is passed as argument to the connection callback provided in the "init" function. This reference can also be retrieve directly when the function getConnection is called.
The "Connection" object exposes the sendPPDU function. Because the card holder have to operate directly with the PCR PAD, the function is asynchronous. The final result is reported to the web page by the callback provided as parameter of the function.
Note that you do not need the Gemalto driver for the PCR to operate PPDU commands.
First you have to provide the feature you want to execute:
Second you have to provide the template for the targeted feature. The template is described in the PC/SC part 10 specification. As parameter of the sendPPDU function, you have to create an empty literal object and populate it with the required fields using the following defined types:
EWC can verify the card holder's PIN using the PPDU mechanism.
In your JavaScript file, you have to get the Connection object, build the verify PIN template and call the sendPPDU function for the verify PIN feature.
var cnx = enex.getConnection( ); if( !cnx ) { showResult( g_sTitleKO, "no available connection to the smart card" ); return; } var parameters = { }; // Time-out in seconds // If this parameter is not set then the PCR default time-out is used. parameters[ enex.FEATURE_PARAMETER_TIMEOUT ] = document.getElementById( "verify_timeOut" ).value; // Time-out in seconds after first key stroke parameters[ enex.FEATURE_PARAMETER_TIMEOUT2 ] = document.getElementById( "verify_timeOut2" ).value; parameters[ enex.FEATURE_PARAMETER_FORMATSTRING ] = document.getElementById( "verify_formatingOptions" ).value; // BYTE PIN size parameters[ enex.FEATURE_PARAMETER_PINBLOCKSTRING ] = document.getElementById( "verify_pinBlockString" ).value; // BYTE parameters[ enex.FEATURE_PARAMETER_PINLENGTHFORMAT ] = document.getElementById( "verify_pinLengthFormat" ).value; // 2 BYTEs parameters[ enex.FEATURE_PARAMETER_PINMAXEXTRADIGIT ] = document.getElementById( "verify_pinMaxExtraDigits" ).value; // BYTE parameters[ enex.FEATURE_PARAMETER_ENTRYVALIDATIONCONDITION ] = document.getElementById( "verify_entryValidationCondition" ).value; // BYTE Number of messages to display for PIN verification parameters[ enex.FEATURE_PARAMETER_NUMBERMESSAGE ] = document.getElementById( "verify_numberMessage" ).value; // 2 bytes Language for messages parameters[ enex.FEATURE_PARAMETER_LANGID ] = document.getElementById( "verify_languageId" ).value; // Byte Message index (should be 00) parameters[ enex.FEATURE_PARAMETER_MSGINDEX ] = document.getElementById( "verify_messageIndex" ).value; // 3 bytes T=1 I-block prologue field to use (fill with 00) parameters[ enex.FEATURE_PARAMETER_TEOPROTOCOL ] = document.getElementById( "verify_teoProtocol" ).value; // 4 bytes length of Data to be sent to the ICC //parameters[ enex.FEATURE_PARAMETER_DATALENGTH ] = document.getElementById( "verify_dataLength" ).value; // x bytes Data to send to the ICC parameters[ enex.FEATURE_PARAMETER_DATA ] = document.getElementById( "verify_data" ).value; // Create the callbacks to receive the response var resultCallback = { success : function( dataOut ) { alert("Operation succeeded - Data returned by the reader(" + dataOut + ")" ); }, failure : function( a_oErrorObject ) { alert("Operation FAILED. Error code (" + a_oErrorObject.errorCode + "). Error message (" + a_oErrorObject.message + ")"); } }; try { cnx.sendPPDU( resultCallback, enex.FEATURE_PARAMETER_FEATURE_VERIFY_PIN_DIRECT, parameters ); } catch( ex ) { // An exception has been thrown before the command was sent to the PCR. alert("Command transmission failed ! " + ex.message ); }
EWC can modify the card holder's PIN using the PPDU mechanism.
In your JavaScript file, you have to get the Connection object, build the modify PIN template and call the sendPPDU function for the modify PIN feature.
function sendModifyPPDU( ) { var cnx = enex.getConnection( ); if( !cnx ) { alert("no available connection to the smart card"); return; } // Create an object to pass all parameters var parameters = { }; // Time-out in seconds // If this parameter is not set then the PCR default time-out is used. parameters[ enex.FEATURE_PARAMETER_TIMEOUT ] = document.getElementById( "modify_timeOut" ).value; // Time-out in seconds after first key stroke parameters[ enex.FEATURE_PARAMETER_TIMEOUT2 ] = document.getElementById( "modify_timeOut2" ).value; parameters[ enex.FEATURE_PARAMETER_FORMATSTRING ] = document.getElementById( "modify_formatingOptions" ).value; // BYTE PIN size parameters[ enex.FEATURE_PARAMETER_PINBLOCKSTRING ] = document.getElementById( "modify_pinBlockString" ).value; // BYTE parameters[ enex.FEATURE_PARAMETER_PINLENGTHFORMAT ] = document.getElementById( "modify_pinLengthFormat" ).value; // 1 BYTEs parameters[ enex.FEATURE_PARAMETER_INSERTIONOFFSETOLD ] = document.getElementById( "modify_insertionOffsetOld" ).value; // 1 BYTEs parameters[ enex.FEATURE_PARAMETER_INSERTIONOFFSETNEW ] = document.getElementById( "modify_insertionOffsetNew" ).value; // 2 BYTEs parameters[ enex.FEATURE_PARAMETER_PINMAXEXTRADIGIT ] = document.getElementById( "modify_pinMaxExtraDigits" ).value; // parameters[ enex.FEATURE_PARAMETER_CONFIRMPIN ] = document.getElementById( "modify_confirmPin" ).value; // BYTE parameters[ enex.FEATURE_PARAMETER_ENTRYVALIDATIONCONDITION ] = document.getElementById( "modify_entryValidationCondition" ).value; // BYTE Number of messages to display for PIN verification parameters[ enex.FEATURE_PARAMETER_NUMBERMESSAGE ] = document.getElementById( "modify_numberMessage" ).value; // 2 bytes Language for messages parameters[ enex.FEATURE_PARAMETER_LANGID ] = document.getElementById( "modify_languageId" ).value; // Byte Message index (should be 00) parameters[ enex.FEATURE_PARAMETER_MSGINDEX1 ] = document.getElementById( "modify_messageIndex1" ).value; // Byte Message index (should be 00) parameters[ enex.FEATURE_PARAMETER_MSGINDEX2 ] = document.getElementById( "modify_messageIndex2" ).value; // Byte Message index (should be 00) parameters[ enex.FEATURE_PARAMETER_MSGINDEX3 ] = document.getElementById( "modify_messageIndex3" ).value; // 3 bytes T=1 I-block prologue field to use (fill with 00) parameters[ enex.FEATURE_PARAMETER_TEOPROTOCOL ] = document.getElementById( "modify_teoProtocol" ).value; // 4 bytes length of Data to be sent to the ICC //parameters[ enex.FEATURE_PARAMETER_DATALENGTH ] = document.getElementById( "modify_dataLength" ).value; // x bytes Data to send to the ICC parameters[ enex.FEATURE_PARAMETER_DATA ] = document.getElementById( "modify_data" ).value; try { cnx.sendPPDU( resultCallback, enex.FEATURE_PARAMETER_FEATURE_MODIFY_PIN_DIRECT, parameters ); } catch( ex ) { // An exception has been thrown before the command was sent to the PCR. alert("Command transmission failed ! " + ex.message); } }
EWC can also get or set the current PCR language. This is done using the ESC Command PPDU feature. The direct call to the sendPPDU have been wrapped into two different functions setPersonalCardReaderLanguage and getPersonalCardReaderLanguage.
function sendChangeLanguage( a_Language, a_bTemporaryChange, a_bCardLanguage ) { var cnx = enex.getConnection( ); if( !cnx ) { alert("no available connection to the smart card"); return; } var lang = document.getElementById( "language_lang" ).value; var temporary = true; if( document.getElementById( "language_permanent" ).checked == true ) { temporary = false; } var overwriteCard = false; if( document.getElementById( "language_overwrite_card" ).checked == true ) { overwriteCard = true; } try { cnx.setPersonalCardReaderLanguage( resultCallback, lang, temporary, overwriteCard ); } catch( ex ) { // An exception has been thrown before the command was sent to the PCR. alert("Command transmission failed ! " + ex.message); } } function sendGetLanguage( ) { var cnx = enex.getConnection( ); if( !cnx ) { alert("no available connection to the smart card"); return; } try { cnx.getPersonalCardReaderLanguage( resultCallback ); getLang = true; } catch( ex ) { // An exception has been thrown before the command was sent to the PCR. alert("Command transmission failed ! " + ex.message); } }