MuscleCard

Please note: The MuscleCard applet is no longer actively maintained. If you are looking for a generic JavaCard applet with OpenSC support to store RSA and ECC cryptographic keys and certificates take a look at the SmartCard-HSM.

MuscleCard is an open source project hosted at the M.U.S.C.L.E website. It aims to develop a JavaCard applet and supporting middleware to perform cryptographic operations like signing and encryption in a smart card.

The Script Collection contains a set of scripts to load the MuscleCard applet into a JavaCard, to create cryptographic keys and examples how to use them. The scripts can be used without any further tools installed, a working Global Platform compliant JavaCard should be sufficient.

Getting started

First thing you need is a working JavaCard. The scripts have been tested with JCOP 3.1, JCOP 4.1 and Cyberflex 64K cards.

Before you start, make sure that the card manager applet in the JavaCard has been initialised with the Global Platform sample keys. Maybe you want to try the "gp/explore.js" script first and authenticate against the card (Expand the "Card Manager" node and right click on "Authenticate"). If that works, then the proper keys have been set.

>load("gp/explore.js");
Exception selecting EF_DIR. Assuming no EF_DIR...
Function (CARD_COMM_ERROR/27270) - SELECT failed with SW1/SW2 = 6A86 "Incorrect P1-P2"
Issuer Identification Number(42)
Card Image Number(45)
Card Data(66)
Key Information Template(e0)
Sequence Counter of the default Key Version Number(c1)
Confirmation Counter(c2)
Sending INIT-UPDATE with host challenge...
Using SCP01...
Input to session key derivation: 1D 68 94 96 E2 DE CC 35 08 FB 07 53 DF A7 EC EB
Input to card cryptogram verification: E2 DE CC 35 DF A7 EC EB 08 FB 07 53 1D 68 94 ...
Input to host cryptogram calculation: 08 FB 07 53 1D 68 94 96 E2 DE CC 35 DF A7 EC ...
Host cryptogram: 90 B7 93 60 0F 31 20 14
Performing external authentication...
Done...

Don't be confused by the error message. This is just because JavaCards do not have an EF_DIR file and the explorer code is somewhat generic for all cards.

Loading the Applet

You will first need to load the MuscleCard applet into your JavaCard. You can use the Smart Card Shell to do that.

Two scripts are provided to load the MuscleCard applet:

If you are using a different JavaCard, it is probably best to try the loadintojcop.js script first. If your card is based on the JTOP runtime, then the loadintocyberflex64.js might be the right choice.

>load("musclecard/loadintocyberflex64.js");
Selecting card manager application...
0000  6F 19 84 08 A0 00 00 00 03 00 00 00 A5 0D 9F 6E  o.............n
0010  06 20 91 01 03 42 75 9F 65 01 FF                 . ...Bu.e.

Sending INIT-UPDATE with host challenge...
Using SCP01...
Input to session key derivation: DD E3 A9 53 90 87 1F 17 28 89 21 B8 B2 10 A0 77
Input to card cryptogram verification: 90 87 1F 17 B2 10 A0 77 28 89 21 B8 DD E3 A9 ..
Input to host cryptogram calculation: 28 89 21 B8 DD E3 A9 53 90 87 1F 17 B2 10 A0 ..
Host cryptogram: 34 AB DE 13 89 C6 B9 E4
Performing external authentication...
Done...
Delete old applet instance...
Delete old load file...
InstallForLoad...
Loading applet...
Instantiating applet...
>

Loading the applet will take approx. 35 seconds. Maybe you want to switch to the "Trace" tab in the shell to see the progress.

The musclecard directory contains two .CAP files with the 0.9.11 version of the MuscleCard applet:

Note: There seems to be a rather big confusion about versions and forks of the original code. It seems, that the Redhat Coolkey Applet is a fork of the 0.9.10 version of the orginal code. Coolkey has extended the original code and added new functions, but it seems to be very much tailored towards Cyberflex.

Applet Initialisation

After loading, the MuscleCard applet must be initialised. This is an undocumented function, normally provided by the MuscleTool. The required initialisation is done by the init.js script.

The script sets default value "12345678" for PIN0, Unblocking-PIN0, PIN1 and Unblocking-PIN1.

The initialisation is only done once. Without initialisation, the applet will always respond with SW1/SW2=9C05 to any APDU received.

>load("musclecard/init.js");
Applet not initialized
08 4D 75 73 63 6C 65 30 30 10 10 08 31 32 33 34 35 36 37 38 08 31 32 33 34 35 36 37 ...
9000
Response to MSCGetStatus command APDU: 00 01 00 06 00 00 10 00 00 00 0F FE 02 00 00 00
Card Edge Major Version        : 0
Card Edge Minor Version        : 1
Software Major Version         : 0
Software Minor Version         : 6
Total Object memory            : 4096
Free Object Memory             : 4094
Number of used PINs            : 2
Number of used Keys            : 0
Currently Logged in Identities : none
>

Query the Applet Status

At any time, you can query the status of the MuscleCard applet, display information about the loaded PINs, objects and keys using the status.js script.

>load("musclecard/status.js");
Response to MSCGetStatus command APDU: 00 01 00 06 00 00 10 00 00 00 0F 63 02 02 00 00
Card Edge Major Version        : 0
Card Edge Minor Version        : 1
Software Major Version         : 0
Software Minor Version         : 6
Total Object memory            : 4096
Free Object Memory             : 3939
Number of used PINs            : 2
Number of used Keys            : 2
Currently Logged in Identities : none
List PINs: PIN0,PIN1 (3)
-- List Objects ------------------------------------------------
  Object Id     : FF FF FF FF
  Size          : 139
  Read Access   : Always (0)
  Write Access  : Always (0)
  Delete Access : Always (0)
0000  00 01 04 00 00 80 8F 00 7E DF 85 C7 4A 8A 31 16  ........~.J.1.
0010  60 8C 4D 35 A5 FA 76 38 9A D5 BB 46 8F 09 72 51  `.M5v8.ջF..rQ
0020  54 B0 16 64 A9 14 9D D8 2C 05 F6 2D FF 12 7F B1  T.d..,.-..
0030  59 F7 23 7B 3E 55 EF E9 DA D7 D1 DF 1B FA FD E6  Y#{>U.
0040  D9 B5 EC E9 BB 03 3D A4 F5 32 62 27 B0 7D C7 52  ٵ.=2b'}R
0050  06 4E 79 D4 77 F7 F1 73 C9 18 6D FE 13 90 DA BA  .Nyws.m..ں
0060  16 8D 93 B8 C2 A8 C3 65 C5 85 90 A6 E3 F1 90 FC  ...¨e...
0070  0E 2C 6B 89 67 6A FD 87 1E F3 D8 5E 26 5A 81 AB  .,k.gj..^&Z.
0080  CB 14 A1 E6 BC F7 00 03 01 00 01                 ......

-- List Keys ---------------------------------------------------
  Key Number    : 0
  Key Type      : RSA_PRIVATE_CRT (3)
  Key Partner   : 255
  Key Size      : 1024
  Read Access   : Never (ffff)
  Write Access  : Never (ffff)
  Use Access    : PIN0 (1)
  Key Number    : 1
  Key Type      : RSA_PUBLIC (1)
  Key Partner   : 255
  Key Size      : 1024
  Read Access   : Always (0)
  Write Access  : Never (ffff)
  Use Access    : Never (ffff)
>

Generating Keys

Once the applet is loaded and initialised, you can start generating key pairs.

If you want to do this directly, then you can try one the the genrsa scripts provided:

>load("musclecard/genrsa1024.js");
Generating key...
0000  00 01 04 00                                      ....

Modulus : 8F 00 7E DF 85 C7 4A 8A 31 16 60 8C 4D 35 A5 FA 76 38 9A D5 BB 46 8F 09 72 ..
Exponent: 01 00 01
>

As you may have noticed, all scripts load tools.js, which provides some generic functions used by the scripts. Feel free to use or extend this for your own purpose.

Signing with the Applet

The newly generated key pair can be used to sign some data. Hashing must be done externally, the MuscleCard applet only performs the RSA encrypt operation. The sample scripts use the CM_RSA_NOPAD option and provide a full size input buffer.

Two scripts, one for each key size, are available:

The script will read the public key from the applet and triggers the signature operation. The resulting block is then decrypted using the public key an verified against the plain value.

>load("musclecard/signrsa2048.js");
Reading public key...
0000  00 01 08 00                                      ....

Modulus : 87 26 18 14 08 23 9E 16 B4 CE D5 74 92 2E 41 C7 03 C6 2A 8D 62 00 74 61 2E ..
Exponent: 01 00 01
Signing data...
0000  49 89 E1 73 C0 4A FD 17 EB 32 8A 40 EE 1C 3A DE  I.sJ.2.@.:
0010  F7 EC E8 3F 2C 78 19 0E 0A 88 09 E5 0A 40 AD D3  ?,x......@
0020  D6 16 10 48 A5 B7 5A 43 81 B1 EA 05 AF D0 91 D8  ..HZC...
0030  97 B1 5B 85 0A 5C 1B 7E 93 B5 6D FC 63 CE FC 07  .[..\.~.mc.
0040  FB A1 F9 7A 2B 56 AD 12 7F E1 34 29 CA 6D 9B C7  z+V..4)m.
0050  B9 66 CD 7F D2 8A AE 20 8E 1A 58 02 7B 9C 4A 27  f.. ..X.{.J'
0060  24 DA AB 2E F7 FE EC 5C 25 33 8E EE 5A 34 9D 62  $ګ.\%3.Z4.b
0070  70 5B 6F 24 27 75 E4 B9 5C 96 E7 64 CC 07 5F 7A  p[o$'u\.d._z
0080  3C 50 62 CC 28 A8 AB 34 49 E7 7B D0 A2 7A 01 25  >Pb(4I{Тz.%
0090  46 F8 47 D8 D1 01 A7 7B 7A 96 18 18 4E 11 EB C8  FG.{z...N.
00A0  A6 FF 32 54 BD 80 E9 5E 01 5F 86 6E 9E CC 41 7C  2T.^._.n.A|
00B0  CE 1C FB 16 CA 9C 33 30 3F 79 39 58 36 47 42 7A  ...30?y9X6GBz
00C0  B1 58 D3 BA 36 4F 70 72 5C 19 28 1F 2C 87 3F 59  XӺ6Opr\.(.,.?Y
00D0  8D 29 9D B3 9D D9 20 58 88 B3 A9 C5 CB 99 87 91  .).. X....
00E0  01 6D 7E F5 6C FF 54 78 21 58 6D D1 A7 E3 75 7A  .m~lTx!Xmѧuz
00F0  54 30 00 26 EC FA 8C EA 8A 6E B8 C0 61 99 57 63  T0.&..na.Wc

0000  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0010  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0020  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0030  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0040  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0050  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0060  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0070  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0080  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
0090  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
00A0  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
00B0  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
00C0  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
00D0  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
00E0  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................
00F0  01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08  ................

>

Using OpenSC with the MuscleCard Applet

Recent versions of the OpenSC tools have support for the MuscleCard applet. We've tested the functionality on Debian with the latest trunk version from SVN. Unfortunately, the latest Smart Card Bundle (0.9) for Windows failed during the pkcs15-init command.

Support for the applet has been build using a file system emulation that maps 2 byte file identifier to 4 byte object identifier in the applet. Using this method, a single level directory and file structure is provided. The file structure emulation is used to store the PKCS#15 meta-data required by OpenSC.

To initialise the PKCS#15 structure on the applet, you will first need to load and initialise the applet itself.

The PKCS#15 structure can be created using the following command (at a command shell, not from within the Smart Card Shell !):

C:\Programme\Smart card bundle>pkcs15-init -C

The program will ask you for a new user PIN first. Please make sure, that you use the default PIN "12345678" from the init.js script. Defining a different PIN will lead to a failure later in the pkcs15-init tool.

The program will also ask for an "Unspecified PIN [reference 1]". This is the same PIN as the user PIN and again the default PIN "12345678" must be entered.

Once the applet is initialised with a PKCS#15 structure, you can display it using:

C:\Programme\Smart card bundle>pkcs15-tool --dump
PKCS#15 Card [MUSCLE]:
        Version        : 1
        Serial number  : 0000
        Manufacturer ID: Identity Alliance
        Last update    : 20070831085533Z
        Flags          : EID compliant

PIN [User PIN]
        Com. Flags: 0x3
        ID        : ff
        Flags     : [0x18], unblock-disabled, initialized
        Length    : min_len:6, max_len:8, stored_len:8
        Pad char  : 0x00
        Reference : 1
        Type      : ascii-numeric
        Path      : 3f005015

The next step is to load a private key and certificate into the applet. This can be done using the following command:

C:\Programme\Smart card bundle>pkcs15-init -S cert.p12 -f PKCS12 -a FF -i 10

Again you will need to provide the user PIN, which should still be the default value "12345678".

The card is fully now initialised. Using pkcs15-tool -dump you can take a look:

C:\Programme\Smart card bundle>pkcs15-tool --dump
PKCS#15 Card [MUSCLE]:
        Version        : 1
        Serial number  : 0000
        Manufacturer ID: Identity Alliance
        Last update    : 20070831092136Z
        Flags          : EID compliant

PIN [User PIN]
        Com. Flags: 0x3
        ID        : ff
        Flags     : [0x18], unblock-disabled, initialized
        Length    : min_len:6, max_len:8, stored_len:8
        Pad char  : 0x00
        Reference : 1
        Type      : ascii-numeric
        Path      : 3f005015

Private RSA Key [Private Key]
        Com. Flags  : 3
        Usage       : [0x22C], sign, signRecover, unwrap, nonRepudiation
        Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract, local
        ModLength   : 1024
        Key ref     : 0
        Native      : yes
        Path        : 3f005015
        Auth ID     : ff
        ID          : 10

X.509 Certificate [/C=DE/O=CardContact/CN=Andreas Schwier/emailAddress=andreas.s
chwier@cardcontact.de]
        Flags    : 2
        Authority: no
        Path     : 3f0050153110
        ID       : 10

X.509 Certificate [/C=DE/O=CardContact/CN=CardContact CA]
        Flags    : 2
        Authority: yes
        Path     : 3f0050153145
        ID       : 45

Deleting the Applet

If you would like to delete the applet, then you can use the provided deleteapplet.js script.

If you only want to remove the PKCS#15 information, then issuing "pkcs15-init -E" is sufficient.