/*
* Quick-Key Toolset Project.
* Copyright (C) 2010 FedICT.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version
* 3.0 as published by the Free Software Foundation.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, see
* http://www.gnu.org/licenses/.
*/
package be.fedict.eidapplet;
import javacard.framework.OwnerPIN;
import javacard.security.KeyBuilder;
import javacard.security.KeyPair;
import javacard.security.RSAPrivateCrtKey;
public class EmptyEidCard extends EidCard {
// these are identical for all eid card applet so share these between
// subclasses
static byte[] dirData, tokenInfoData, odfData, aodfData, prkdfData, cdfData;
static byte[] citizenCaCert, rrnCert, rootCaCert;
// save some more memory by making the photo static as well
static byte[] photoData;
/**
* called by the JCRE to create an applet instance
*/
public static void install(byte[] bArray, short bOffset, byte bLength) {
// create a sample eID card applet instance
new EmptyEidCard();
}
/**
* private constructor - called by the install method to instantiate a
* SampleEidCard instance
*
* needs to be protected so that it can be invoked by subclasses
*/
protected EmptyEidCard() {
super();
// initialize PINs to fixed value
initializePins();
// initialize file system
initializeFileSystem();
// initialize place holders for large files (certificates + photo)
initializeEmptyLargeFiles();
// initialize basic keys pair
initializeKeyPairs();
}
/**
* initialize all the PINs
*
* PINs are set to the same values as the sample eID card
*/
private void initializePins() {
/*
* initialize cardholder PIN (hardcoded to fixed value)
*
* PIN header is "24" (length of PIN = 4) PIN itself is "1234" (4
* digits) fill rest of PIN data with F
*/
byte[] cardhold = { (byte) 0x24, (byte) 0x12, (byte) 0x34, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
cardholderPin = new OwnerPIN(CARDHOLDER_PIN_TRY_LIMIT, PIN_SIZE);
cardholderPin.update(cardhold, (short) 0, PIN_SIZE);
/*
* initialize unblock PUK (hardcoded to fixed value)
*
* PUK header is "2c" (length of PUK = 12) PUK itself consists of 2
* parts PUK2 is "222222" (6 digits) PUK1 is "111111" (6 digits) so in
* total the PUK is "222222111111" (12 digits) fill last bye of PUK data
* with "FF"
*/
byte[] unblock = { (byte) 0x2c, (byte) 0x22, (byte) 0x22, (byte) 0x22, (byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0xFF };
unblockPin = new OwnerPIN(UNBLOCK_PIN_TRY_LIMIT, PIN_SIZE);
unblockPin.update(unblock, (short) 0, PIN_SIZE);
/*
* activation PIN is same as PUK
*/
activationPin = new OwnerPIN(ACTIVATE_PIN_TRY_LIMIT, PIN_SIZE);
activationPin.update(unblock, (short) 0, PIN_SIZE);
/*
* initialize reset PIN (hardcoded to fixed value)
*
* PUK header is "2c" (length of PUK = 12) PIN itself consists of 2
* parts PUK3 is "333333" (6 digits) PUK1 is "111111" (6 digits) so in
* total the PIN is "333333111111" (12 digits) fill last bye of PIN data
* with "FF"
*/
byte[] reset = { (byte) 0x2c, (byte) 0x33, (byte) 0x33, (byte) 0x33, (byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0xFF };
resetPin = new OwnerPIN(RESET_PIN_TRY_LIMIT, PIN_SIZE);
resetPin.update(reset, (short) 0, PIN_SIZE);
}
/**
* Initialise all files on the card as empty with max size
*
* see "Belgian Electronic Identity Card content" (version x)
*
* depending on the eid card version, the address is of different length
* (current: 117)
*/
private void initializeFileSystem() {
masterFile = new MasterFile();
/*
* initialize PKCS#15 data structures see
* "5. PKCS#15 information details" for more info
*/
dirFile = new ElementaryFile(EF_DIR, masterFile, (short) 0x25);
belpicDirectory = new DedicatedFile(DF_BELPIC, masterFile);
tokenInfo = new ElementaryFile(TOKENINFO, belpicDirectory, (short) 0x30);
objectDirectoryFile = new ElementaryFile(ODF, belpicDirectory, (short) 40);
authenticationObjectDirectoryFile = new ElementaryFile(AODF, belpicDirectory, (short) 0x40);
privateKeyDirectoryFile = new ElementaryFile(PRKDF, belpicDirectory, (short) 0xB0);
certificateDirectoryFile = new ElementaryFile(CDF, belpicDirectory, (short) 0xB0);
idDirectory = new DedicatedFile(DF_ID, masterFile);
/*
* initialize all citizen data stored on the eID card copied from sample
* eID card 000-0000861-85
*/
// initialize ID#RN EF
identityFile = new ElementaryFile(IDENTITY, idDirectory, (short) 0xD0);
// initialize SGN#RN EF
identityFileSignature = new ElementaryFile(SGN_IDENTITY, idDirectory, (short) 0x80);
// initialize ID#Address EF
// address is 117 bytes, and should be padded with zeros
addressFile = new ElementaryFile(ADDRESS, idDirectory, (short) 117);
// initialize SGN#Address EF
addressFileSignature = new ElementaryFile(SGN_ADDRESS, idDirectory, (short) 128);
// initialize PuK#7 ID (CA Role ID) EF
caRoleIDFile = new ElementaryFile(CA_ROLE_ID, idDirectory, (short) 0x20);
// initialize Preferences EF to 100 zero bytes
preferencesFile = new ElementaryFile(PREFERENCES, idDirectory, (short) 100);
}
/**
* initialize empty files that need to be filled latter using UPDATE BINARY
*/
private void initializeEmptyLargeFiles() {
/*
* these 3 certificates are the same for all sample eid card applets
* therefor they are made static and the data is allocated only once
*/
caCertificate = new ElementaryFile(CA_CERTIFICATE, belpicDirectory, (short) 1200);
rrnCertificate = new ElementaryFile(RRN_CERTIFICATE, belpicDirectory, (short) 1200);
rootCaCertificate = new ElementaryFile(ROOT_CA_CERTIFICATE, belpicDirectory, (short) 1200);
/*
* to save some memory we only support 1 photo for all subclasses
* ideally this should be applet specific and have max size 3584 (3.5K)
*/
photoFile = new ElementaryFile(PHOTO, idDirectory, (short) 3584);
/*
* certificate #2 and #3 are applet specific allocate enough memory
*/
authenticationCertificate = new ElementaryFile(AUTH_CERTIFICATE, belpicDirectory, (short) 1200);
nonRepudiationCertificate = new ElementaryFile(NONREP_CERTIFICATE, belpicDirectory, (short) 1200);
}
/**
* initialize basic key pair
*/
private void initializeKeyPairs() {
/*
* basicKeyPair is static (so same for all applets) so only allocate
* memory once
*/
if (EidCard.basicKeyPair != null)
return;
basicKeyPair = new KeyPair(KeyPair.ALG_RSA_CRT, (short) 1024);
basicKeyPair.genKeyPair();
authKeyPair = new KeyPair(KeyPair.ALG_RSA_CRT, (short) (1024));
authKeyPair.genKeyPair();
//authPrivateKey = (RSAPrivateCrtKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_CRT_PRIVATE, KeyBuilder.LENGTH_RSA_1024, false);
nonRepKeyPair = new KeyPair(KeyPair.ALG_RSA_CRT, (short) (1024));
nonRepKeyPair.genKeyPair();
//nonRepPrivateKey = (RSAPrivateCrtKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_CRT_PRIVATE, KeyBuilder.LENGTH_RSA_1024, false);
}
}