1 /*
  2  *  ---------
  3  * |.##> <##.|  Open Smart Card Development Platform (www.openscdp.org)
  4  * |#       #|  
  5  * |#       #|  Copyright (c) 1999-2006 CardContact Software & System Consulting
  6  * |'##> <##'|  Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de)
  7  *  --------- 
  8  *
  9  *  This file is part of OpenSCDP.
 10  *
 11  *  OpenSCDP is free software; you can redistribute it and/or modify
 12  *  it under the terms of the GNU General Public License version 2 as
 13  *  published by the Free Software Foundation.
 14  *
 15  *  OpenSCDP is distributed in the hope that it will be useful,
 16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18  *  GNU General Public License for more details.
 19  *
 20  *  You should have received a copy of the GNU General Public License
 21  *  along with OpenSCDP; if not, write to the Free Software
 22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 23  *
 24  *  Sign with a 2048 bit RSA key
 25  *  Key must have been generated with genrsa2048.js
 26  */
 27 
 28 load("tools.js");
 29 
 30 var card = new Card(_scsh3.reader);
 31 card.reset(Card.RESET_COLD);
 32 
 33 
 34 // Select Applet
 35 card.sendApdu(0x00, 0xA4, 0x04, 0x00, mcaid, [0x9000]);
 36 
 37 print("Reading public key...");
 38 // MSCExportKey
 39 card.sendApdu(0xB0, 0x34, 0x03, 0x00, new ByteString("00", HEX), [0x9000]);
 40 
 41 var kb = readKeyBlob(card);
 42 
 43 print(kb.header);
 44 print("Modulus : " + kb[0]);
 45 print("Exponent: " + kb[1]);
 46 
 47 var puk = new Key();
 48 puk.setType(Key.PUBLIC);
 49 puk.setComponent(Key.MODULUS, kb[0]);
 50 puk.setComponent(Key.EXPONENT, kb[1]);
 51 
 52 // MSCVerifyPIN
 53 card.sendApdu(0xB0, 0x42, 0x00, 0x00, new ByteString("12345678", ASCII), [0x9000]);
 54 
 55 print("Signing data...");
 56 //var msg = new ByteString("Hello World", ASCII);
 57 var msg = new ByteString("01020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708", HEX);
 58 
 59 // MSCComputeCrypt / Cipher Init / data = cipher mode | cipher direction | data location | chunk size (2) | chunk
 60 // Warning: cipher mode definition in mcardprot-1.2.1.pdf is wrong for RSA_NO_PAD(=0) and RSA_PAD_PKCS1(=1)
 61 card.sendApdu(0xB0, 0x36, 0x02, 0x01, new ByteString("0003010000", HEX), [0x9000]);
 62 
 63 var data = new ByteBuffer();
 64 data.append(msg.length >> 8);
 65 data.append(msg.length && 0xFF);
 66 data.append(msg);
 67 
 68 // MSCCreateObject
 69 card.sendApdu(0xB0, 0x5A, 0x00, 0x00, new ByteString("FFFFFFFE00000102000000000000", HEX), [0x9000]);
 70 
 71 // MSCWriteObject
 72 var body = (new ByteString("FFFFFFFE0000000082", HEX)).concat(data.toByteString().bytes(0x00, 0x82));
 73 var resp = card.sendApdu(0xB0, 0x54, 0x00, 0x00, body, [0x9000]);
 74 var body = (new ByteString("FFFFFFFE0000008280", HEX)).concat(data.toByteString().bytes(0x82, 0x80));
 75 var resp = card.sendApdu(0xB0, 0x54, 0x00, 0x00, body, [0x9000]);
 76 
 77 
 78 // MSCComputeCrypt / Cipher Final / data = data location
 79 card.sendApdu(0xB0, 0x36, 0x02, 0x03, new ByteString("02", HEX), [0x9000]);
 80 
 81 var resp = card.sendApdu(0xB0, 0x56, 0x00, 0x00, new ByteString("FFFFFFFF00000000FF", HEX), [0x9000]);
 82 resp = resp.concat(card.sendApdu(0xB0, 0x56, 0x00, 0x00, new ByteString("FFFFFFFF000000FF03", HEX), [0x9000]));
 83 var cryptogram = resp.bytes(2);
 84 print(cryptogram);
 85 
 86 var crypto = new Crypto();
 87 
 88 var plain = crypto.decrypt(puk, Crypto.RSA, cryptogram);
 89 print(plain);
 90 
 91 assert(plain.equals(msg));
 92