Smart Card Shell

Getting Started

At this point you should have installed the Smart Card Shell. If not, please have a look at the installation instructions.

After you started the Smart Card Shell and selected a working directory, you will see a window divided into two panes. The left pane will be empty and the right pane will show a text area, which works as a console and is the main user interface of the Smart Card Shell.

The left pane is called the outline. It will be filled with informations generated when you run scripts. You can drag the divider between the two panes and change the amount of space allocated to the outline and the text area.

To end the shell, you can either enter "quit" into the text area or select "Exit" from the "File" menu.

Quick Start

Insert a smart card into your reader and enter:

> r

If everythings is installed correctly, then you should see the Answer to Reset (ATR) for your card.

If you feel like more, try

> load("tools/explore.js");

and see for yourself.

Understanding the Shell Concept

The Smart Card Shell uses a JavaScript interpreter and compiler to execute scripts. JavaScript is a typeless, object-oriented programming language commonly used in web browsers for active HTML pages. The language syntax is very similar to Java and C.

The shell is directly connected to the JavaScript interpreter, so any input in the text area must be valid JavaScript code. Whenever you enter a command into the shell, this command is evaluated by the interpreter, executed and the resulting value displayed to the user. Give it a try and enter:

> 1000 + 2000

After pressing ENTER the shell will display

3000
>

and is ready to accept the next command.

Invoking functions is as simple. To print something on the command line or from within a script you can invoke the print() function. The print() function will print all passed arguments separated by a whitespace and a final line break.

> print("Value", 100, 200);

will result in

Value 100 200
>

When entering a function name without parentheses, the shell will invoke this function with the result of the previous command as argument. This can be quite handy, if you define functions which shall continue processing on the output of the previous function. However this functionality is only available when entering commands in the shell. When writing scripts, you need to store the result in a variable instead.

The help() function can be invoked with or without parentheses and it will display a short help text. The function itself is defined in the CONFIG.JS script, which is run as the initial configuration script when you start the shell.

Don't be surprised, if only a few commands are build-in commands. Most of the time you will write and use scripts to do something with the Smart Card Shell.

Variables can be assigned a value without prior declaration. The script interpreter will take care of the best storage type and any conversion necessary.

You can define global and local variables. Global variables are created when you first assign a value to it:

> globalVariable = "Test";
creates a global variable named globalVariable and with a string value "Test". Local variable are declared with a var prefix:
> var localVariable = "Hello";

Local variables are only valid within the function in which they are defined.

Running Scripts

Most of the time you will run scripts that are either supplied with the Smart Card Shell or which you developed for your own purpose. A script can be compiled and executed using the load() method build into the scripting enviroment.

The load() method accepts a string as the script name:

> load("tools/explore.js");

Remember, that all commands entered in the shell must be valid JavaScript code. Specifying a full path requires you to escape the backslash character with an additional backslash, because this notation is required for string literals:

> load("c:\\myscripts\\explore.js");

For your own convenience and better portability to other operating systems, we recommend to use the forward slash instead. This does not need to be escaped:

> load("c:/myscripts/explore.js");

You can also run scripts from the "File" / "Run Script" menu or by entering CTRL-R.

The shell is using a simple scheme to map file names used in scripts to files in the operating environment. As a rule of thumb, all file names are resolved relative to the location of the script which is currently running. If a file cannot be found relative to the location of the script, then in turn the working directory and the installation directory is searched. See Locating Files for details.

The scripts supplied with the Smart Card Shell are located in directories underneath the installation directory (Usually "c:\Program Files\CardContact\Smart Card Shell 3"). The tools directory contains a number of scripts that provide support for common tasks. Other directories contain script for specific card applications (e.g. ICAO MRTD, EMV, GeldKarte, eGK and HPC)

Selecting a Card Reader

Unless you explicitly selected a card reader from the "Options" / "Reader Configuration", the shell will use the first card reader in the system as default reader. Once you select a card reader, the JavaScript variable _scsh3.reader will be set to the name of the reader. You can reference this configuration variable in your own scripts.

Defining and Using Objects

JavaScript supports object-oriented programming, but uses prototype objects rather than classes. A prototype object contains the common properties of all instances of the same object. Common properties can be, for example, constants and methods.

Objects are created using the new operator. Following the new operator you can define a function that acts as a constructor. You can pass arguments to this function to initialize the newly created object.

Constructor functions in JavaScript are similar to classes in Java. By defining a constructor function and assigning other functions to the prototype of a constructor you can build your own objects and methods. The following code shows the concept:

//
// Define constructor and class Point
//
function Point(x, y) {
        this.x = x;
        this.y = y;
}

//
// Define method add() and assign to the prototype object, making it available
// for all instances created with the Point constructor function
//
Point.prototype.add = function(x, y) {
        this.x += x;
        this.y += y;
}

//
// Define a toString() method
//
Point.prototype.toString = function() {
        return("y = " + this.x + ", y = " + this.y);
}

var p = new Point(10, 20);

p.add(20, 10);
print(p);

The Smart Card Shell supports a large number of predefined classes (aka constructor functions) and methods to work with smart cards, cryptographic material, data structures and PKI services. See the main page for a complete reference of Global Platform and shell scripting classes.

Using Modules

The Smart Card Shell supports modules as defined in the CommonJS specification.

A module is a script that exports functions that other scripts or modules can use. Modules have their own top level scope, so global variables or functions declared in a module are only visible within the module. Only functions or variables declared in the export variable are visible to others.

A module can be included using the require() statement, which returns the contents of the export variable from the module:

CVC = require('scsh/eac/CVC').CVC;

The above statements inspects the cache for a module with the id scsh/eac/CVC. If no such module exists in the internal cache, then the Smart Card Shell locates the module file CVC.js, executes it and stores the resulting exports in the cache. Modules are executed only once, so transitive use in other modules is possible and effective.

To declare a module, you must assign your exports to the variable exports defined in the module scope:

function CVC() {
	...
}

exports.CVC = CVC;

In the module, you can use the variable module to access the module id and module URI. The module id is the id used in the require() statement, while the URI is the absolute filename where the module was loaded from.

print(module.id);
print(module.uri);

outputs for a module included with require('scsh/eac/CVC') from a user workspace (USR) /home/user/scsh_workspace:

scsh/eac/CVC
/home/user/scsh_workspace/scsh/eac/CVC.js

If you need to access resources relative to the location of the module, then the recommended way is to extract the module path from the module URI:

// Remove "file:" and trailing module name
modulepath = module.uri.substr(0, module.uri.lastIndexOf("/")).substr(5);