Using Remote Smart Card Access
Remote smart card access in the Scripting Server allows you to connect a remote smart card to a web application on the server.
This mechanism allows you to do things like
- read data from a smart card in a web application,
- use a smart card to log into a web application,
- integrate a digital signature in your web application,
- issue certificates remotely,
- remotely personalize a smart card or
- manage secure elements from a trusted service manager.
The remote terminal support implements the Global Platform Remote Application Management over HTTP protocol (RAMOverHTTP). This protocol is widely implemented by Trusted Service Manager to securely manage JavaCard applications on a secure element. The protocol provides for a transparent APDU channel using HTTP. Despite it's name, it's perfectly suited to obtain transparent access to a smart card located at the client.
The protocol requires a server and a client component. While the Scripting Server provides the server side, the client component is part of the OpenCard Framework (OCF). The OpenCard Framework provides a client that can be integrated in a Java application, a command line client to connect from scripts or a tray application running as a daemon process.
Interaction between the Client and the Server
The RAMOverHTTP protocol defines a TLV container for a command and response template exchanged via HTTP POST. The client initiates the session with a connect to the server. The server responds with the first command template containing one or more APDUs.
APDUs are forwarded to the card at the client and the response APDUs are collected. If all commands in the template are executed by the card, then the response template is send to the server in a next HTTP POST. If the server wants to send more APDUs, then those are included in response to the POST request. If the server has no more commands to send, the response is empty and the session is closed.
Mapping the protocol to the Scripting Environment
Whenever the server receives a new session from the client, a card terminal instance under the session id is created and a new thread
is started calling the performCardUpdate()
method in the global scope:
function performCardUpdate(session, pathInfo) {
GPSystem.trace("Request received for session " + session.id + " at " + pathInfo);
var card = new Card(session.cardTerminal);
try {
var atr = card.reset(Card.RESET_COLD);
print(atr);
session.cardTerminal.sendNotification(0, "Test");
card.sendApdu(0x00, 0x20, 0x00, 0x81);
if (card.SW != 0x9000) {
var aid = new ByteString("E82B0601040181C31F0201", HEX);
var rsp = card.sendApdu(0x00, 0xA4, 0x04, 0x04, aid, 0, [0x9000]);
card.sendApdu(0x00, 0x20, 0x00, 0x81, new ByteString("648219", ASCII));
}
for (var i = 0; i <= 1; i++) {
print(i);
var rsp = card.sendApdu(0x00, 0x84, 0x00, 0x00, 0x45, [0x9000]);
}
}
finally {
card.close();
}
}
The above example connects with the remote card in the var card = new Card(session.id)
statement. It then
sends a reset to the remote card reader and receives the ATR of the card inserted. It sends a notification to the remote
user via the ct.sendNotification()
mechanism. The message code and message string can be used to keep the user
informed about the card transaction taking place.
The next couple of lines select a SmartCard-HSM inserted into the remote card reader and obtain a number of random numbers.
Finally the communication channel is closed in the card.close()
statement. The card terminal is removed when the
performCardUpdate()
method returns.
In the script you can of course use all classes and mechanisms defined in the OpenSCDP scripting environment. The above example is contained in the js/cardupdate directory of the Scripting Server bundle.
Running the Client
The simplest way to perform a card session with the server is to connect to the server with the OCF command line tool:
C:\Projects\OpenSCDP\OCF\build\lib>java -jar ocf-cc.jar http://localhost:8080/rt
/test
Connecting to http://localhost:8080/rt/test
Test
78 C: 00 20 00 81 - VERIFY
R: SW1/SW2=6E00 (Checking error: Class not supported) Lr=0
78 C: 00 A4 04 04 - SELECT Lc=11
0005 E8 2B 06 01 04 01 81 C3 1F 02 01 .+.........
Le=0
R: SW1/SW2=9000 (Normal processing: No error) Lr=9
0000 62 07 82 01 78 85 02 01 02 b...x....
78 C: 00 20 00 81 - VERIFY Lc=6
0005 36 34 38 32 31 39 648219
R: SW1/SW2=6700 (Checking error: Wrong length) Lr=0
78 C: 00 84 00 00 - GET CHALLENGE Le=69
R: SW1/SW2=9000 (Normal processing: No error) Lr=69
0000 6A 52 35 70 52 FA 0D 2F C0 59 64 CC 69 7A 73 0D jR5pR../.Yd.izs.
0010 11 56 F3 E3 3C E1 1A 0C B7 61 60 1E E8 89 B2 52 .V..<....a`....R
0020 75 68 18 67 84 4A 37 41 4E 54 E8 8E CF CB E3 3E uh.g.J7ANT.....>
0030 86 1B B9 C6 A1 88 8F 3B FC C8 30 22 5D 77 A8 0E .......;..0"]w..
0040 D4 AD 2E 79 44 ...yD
78 C: 00 84 00 00 - GET CHALLENGE Le=69
R: SW1/SW2=9000 (Normal processing: No error) Lr=69
0000 78 E2 A7 4E 65 0F BD 70 20 16 86 60 B0 F2 5F 33 x..Ne..p ..`.._3
0010 73 43 11 AA 95 4B 76 C4 C7 73 9B 57 C9 81 4C 63 sC...Kv..s.W..Lc
0020 51 D9 5D B3 3B 9E 43 C0 59 CC F3 E3 AA CA 02 90 Q.].;.C.Y.......
0030 2D BB CE 51 71 45 AD AE 31 7B AF 81 47 B8 A5 6E -..QqE..1{..G..n
0040 2E 7D 63 61 E6 .}ca.
Update complete
Running the Client in Daemon Mode
As running the client manually does not provide good usablity for a web application, an alternative way of running the client is available with the OCF daemon mode.
In OCF daemon mode, the OCF client listens for local connects on port 27001, extracts parameters from the connecting URL and starts the session with the server. In a web application this local connect can be embedded in the web page e.g. using the <img> element:
<img height="16" width="16"
onload="window.location.reload()"
src="http://localhost:27001/1296065.png?url=http://localhost:8080/scriptingserver/rt/testappl&sessionId=1n6bij7b4v0di" />
When the browser renders the web page, it tries to load an image from the URL http://localhost:27001/1296065.png, passing the
parameters url
and sessionId
to the OCF daemon. The name of the image resource is ignored by the OCF client,
however the name should be a random value to prevent the browser from using a cached image.
The url
parameter contains the URL the OCF client shall connect to.
The sessionId
parameter is used by the OCF client to generate a session cookie that links the card update session with
the browser session at the server. This way the server application can link card updates with a browser session.
The client also accepts the pinrequired
parameter with a PIN number as argument. Using the pinrequired
parameter in the URL, the OCF client will make sure that the requested PIN is verified before a connection to the server is started. This
way the server can request a local PIN verification using a local pop-up windows or attached PIN pad reader.
A local request will return a small image that denotes a passed or failed operation.
The daemon can be started by running the ocf-cc.jar with a double-click or by entering
java -jar ocf-cc.jar
To test the daemon enter http://127.0.0.1:27001
in your browser to show the red failure icon.
If you are running the client from the desktop, then it will show an icon in the desktop tray. Click on the icon to stop the daemon or to open a trace log window.
For security reasons, the OCF client will request the user to approve the URL the client connects to. The URL can be approved once or
for all subsequent session. The list of approved URLs is contained in the .card-update-servers
text file in the user directory.
© Copyright 2003 - 2020 CardContact Systems GmbH , Minden, Germany