//
// This program overwrites file EF_CHV1 (0x0000) on the smart card with
// 23 bytes of default data and consequently unblocks CHV1 - if it was
// blocked by accident (such as if you typed in the wrong CHV1 three times).
//
// The card for which this program is written, is Multi-Function IBM MFC 4.1
// that ships with the book "Smart Card Application Development Using Java"
// (Authors: Uwe Hansmann, Martin S. Nicklous, Thomas Schaeck, 
// Achim Schneider, Frank Seliger. ISBN 3-540-43202-7 Springer).
//
// The book discusses smart cards in general, and the OpenCard Framework
// (OCF). The book is really good - it's what gave me the boost with 
// smartcards, everything else I found on the net was of lower quality.
//
//
// As stated, the CHV1 is unlocked as a consequence of overwriting
// EF_CHV1 with default data. To overwrite it, however, you need to
// know CHV2 (file 0x0100).
// On the card shipped, both CHV1 and CHV2 are simply "password". Also for
// both files, the unlock password is "unblckpw", but we don't use it here.
//
// To change the data that is written, search for "DEFAULT" in this file.
//
// I've written this (and more on Java & OpenCard - see website below) as
// part of the Computer Communications class assignment at the
// Faculty of Computer and Information Science, Ljubljana, Slovenia.
//
// Enjoy,
// Davor Ocelic, docelic@mail.inet.hr
// http://colt.projectgamma.com
// Jun 28, 2005.
//
//
// To compile, run  javac UnblockCHV1.java
// To run, run      java UnblockCHV1
//
// For installing the whole OpenCard framework on Linux,
// see http://colt.projectgamma.com/oc/opencard-setup.html
//

import opencard.core.service.SmartCard;
import opencard.core.service.CardRequest;
import opencard.opt.iso.fs.FileAccessCardService;
import opencard.opt.iso.fs.CardFile;
import opencard.opt.iso.fs.CardFileOutputStream;

public class UnblockCHV1 {
	public static void main (String args[]) {
		System.out.println("Getting handle on CHV1 - 0x0000");

		try {
			SmartCard.start();

			CardRequest cr = new CardRequest(CardRequest.ANYCARD, null, 
					FileAccessCardService.class);

			SmartCard sc = SmartCard.waitForCard(cr);

			if ( sc == null ) {

					// Error
				
			} else {
				FileAccessCardService facs = (FileAccessCardService)
					sc.getCardService(FileAccessCardService.class, true);
				
				CardFile root = new CardFile(facs);
				CardFile file = new CardFile(root, ":0000");
				CardFileOutputStream outf = new CardFileOutputStream(file);

				// DEFAULT data
				byte outdata[] = new byte[23];

				                   // Description of bytes taken from the book:
				outdata[0]  = 1;   // Activation
				outdata[1]  = 0;   // Way to present
				outdata[2]  = 0;   // Key number in relevant EF_KEY
				outdata[3]  = 'p'; // Password (8 bytes)
				outdata[4]  = 'a';
				outdata[5]  = 's';
				outdata[6]  = 's';
				outdata[7]  = 'w';
				outdata[8]  = 'o';
				outdata[9]  = 'r';
				outdata[10] = 'd';
				outdata[11] = 3;   // Initial attempt counter
				outdata[12] = 3;   // Remaining attempts
				outdata[13] = 'u'; // Unblock password (8 bytes)
				outdata[14] = 'n';
				outdata[15] = 'b'; 
				outdata[16] = 'l';
				outdata[17] = 'c';
				outdata[18] = 'k';
				outdata[19] = 'p';
				outdata[20] = 'w';
				outdata[21] = 1;   // Initial attempt counter
				outdata[22] = 1;   // Remaining attempts

				try { outf.write(outdata); }
				catch (Exception e) { e.printStackTrace(); }

				outf.close();
				sc.close();
			}

		} catch (Exception e) {
			e.printStackTrace();
			
		} finally {
			try { SmartCard.shutdown(); }
			catch (Exception e) { e.printStackTrace(); }
		}

		System.exit(0);
	}
}

