src/com/makina/security/OpenFIPS201/PIV.java
public void putDataAdmin(byte[] buffer, short offset, short length) {

        final byte CONST_TAG_COMMAND 			= (byte)0x30;
        final byte CONST_TAG_OPERATION 	 		= (byte)0x8A;
        final byte CONST_TAG_ID	 	 			= (byte)0x8B;
        final byte CONST_TAG_MODE_CONTACT		= (byte)0x8C;
        final byte CONST_TAG_MODE_CONTACTLESS	= (byte)0x8D;
        final byte CONST_TAG_KEY_MECHANISM 		= (byte)0x8E;
        final byte CONST_TAG_KEY_ROLE	 		= (byte)0x8F;

        final byte CONST_OP_DATA				= (byte)0x01;
        final byte CONST_OP_KEY					= (byte)0x02;

        //
        // SECURITY PRE-CONDITION
        //

        // The command must have been sent over SCP with CEnc+CMac
        if (!cspPIV.checkAccessModeAdmin(true)) {
            ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
        }

        //
        // COMMAND CHAIN HANDLING
        //

        // Pass the APDU to the chainBuffer instance first. It will return zero if there is store more
        // to of the chain to process, otherwise it will return the length of the large CDATA buffer
        length = chainBuffer.processIncomingAPDU(buffer, offset, length, scratch, (short)0);

        // If the length is zero, just return so the caller can keep sending
        if (length == 0) return;

        // If we got this far, the scratch buffer now contains the incoming command. Keep in mind that
        // the original buffer still contains the APDU header.

        // Initialise our TLV reader
        tlvReader.init(scratch, (short)0, length);


        //
        // PRE-CONDITIONS
        //

        // PRE-CONDITION 1 - The 'COMMAND' constructed tag must be present
        if (!tlvReader.match(CONST_TAG_COMMAND)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);

        // Move into the constructed tag
        tlvReader.moveInto();

        // PRE-CONDITION 2 - The mandatory 'OPERATION' tag must be present with length 1
        if (!tlvReader.match(CONST_TAG_OPERATION)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        byte operation = tlvReader.toByte();

        // PRE-CONDITION 3 - The 'OPERATION' value must be set to the value CONST_OP_DATA or CONST_OP_KEY
        if (operation != CONST_OP_DATA && operation != CONST_OP_KEY) ISOException.throwIt(ISO7816.SW_WRONG_DATA);

        // Move to the next tag
        tlvReader.moveNext();

        // PRE-CONDITION 4 - The 'ID' value must be present with length 1
        if (!tlvReader.match(CONST_TAG_ID)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        byte id = tlvReader.toByte();

        // Move to the next tag
        tlvReader.moveNext();

        // PRE-CONDITION 5 - The 'MODE CONTACT' value must be present with length 1
        if (!tlvReader.match(CONST_TAG_MODE_CONTACT)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        byte modeContact = tlvReader.toByte();

        // Move to the next tag
        tlvReader.moveNext();

        // PRE-CONDITION 6 - The 'MODE CONTACTLESS' value must be present with length 1
        if (!tlvReader.match(CONST_TAG_MODE_CONTACTLESS)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        byte modeContactless = tlvReader.toByte();

        byte keyMechanism = ID_ALG_DEFAULT;
        byte keyRole = PIVKeyObject.ROLE_NONE;

        // Move to the next tag
        tlvReader.moveNext();

        if (CONST_OP_KEY == operation) {

            // PRE-CONDITION 7a - If the operation is CONST_OP_KEY, then the 'KEY MECHANISM' tag
            //					 must be present with length 1
            if (!tlvReader.match(CONST_TAG_KEY_MECHANISM)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
            if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
            keyMechanism = tlvReader.toByte();

            // Move to the next tag
            tlvReader.moveNext();

            // PRE-CONDITION 8a - If the operation is CONST_OP_KEY, then the 'KEY ROLE' tag
            //					 must be present with length 1

            if (!tlvReader.match(CONST_TAG_KEY_ROLE)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
            if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
            keyRole = tlvReader.toByte();

            // PRE-CONDITION 9a - If 'OPERATION' is set to CONST_OP_KEY, the key referenced by the 'id' and
            //					  'mechanism' values must not already exist in the key store
            if (cspPIV.selectKey(id, keyMechanism) != null) {
                ISOException.throwIt(ISO7816.SW_FILE_FULL);
            }

        } else { //(CONST_OP_DATA == operation)

            // PRE-CONDITION 7b - If 'OPERATION' is set to CONST_OP_DATA, the object referenced by 'id' value
            // 					 must not already exist in the data store
            PIVObject obj = firstDataObject;
            while (obj != null) {
                if (obj.getId() == id) ISOException.throwIt(ISO7816.SW_FILE_FULL);
                obj = obj.nextObject;
            }
        }


        //
        // EXECUTION STEPS
        //

        // STEP 1 - If the operation is a DATA OBJECT, add it to the data store
        if (operation == CONST_OP_DATA) {
            createDataObject(id, modeContact, modeContactless);
        } else { // (operation == CONST_OP_KEY)
            cspPIV.createKey(id, modeContact, modeContactless, keyMechanism, keyRole);
        }
    }
/**
     * This is the administrative equivalent for the PUT DATA card and is intended for
     * use by Card Management Systems to generate the on-card file-system.
     *
     * @param buffer - The incoming APDU buffer
     * @param offset - The starting offset of the CDATA section
     * @param length - The length of the CDATA section
     */
This is the administrative equivalent for the PUT DATA card and is intended for
use by Card Management Systems to generate the on-card file-system.

@param buffer - The incoming APDU buffer
@param offset - The starting offset of the CDATA section
@param length - The length of the CDATA section
This is the administrative equivalent for the PUT DATA card and is intended for use by Card Management Systems to generate the on - card file - system . @param buffer - The incoming APDU buffer @param offset - The starting offset of the CDATA section @param length - The length of the CDATA section
public void putDataAdmin(byte[] buffer, short offset, short length) {
        final byte CONST_TAG_COMMAND 			= (byte)0x30;
        final byte CONST_TAG_OPERATION 	 		= (byte)0x8A;
        final byte CONST_TAG_ID	 	 			= (byte)0x8B;
        final byte CONST_TAG_MODE_CONTACT		= (byte)0x8C;
        final byte CONST_TAG_MODE_CONTACTLESS	= (byte)0x8D;
        final byte CONST_TAG_KEY_MECHANISM 		= (byte)0x8E;
        final byte CONST_TAG_KEY_ROLE	 		= (byte)0x8F;
        final byte CONST_OP_DATA				= (byte)0x01;
        final byte CONST_OP_KEY					= (byte)0x02;
         SECURITY PRE-CONDITION
         The command must have been sent over SCP with CEnc+CMac
        if (!cspPIV.checkAccessModeAdmin(true)) {
            ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
        }
         COMMAND CHAIN HANDLING
         Pass the APDU to the chainBuffer instance first. It will return zero if there is store more
         to of the chain to process, otherwise it will return the length of the large CDATA buffer
        length = chainBuffer.processIncomingAPDU(buffer, offset, length, scratch, (short)0);
         If the length is zero, just return so the caller can keep sending
        if (length == 0) return;
         If we got this far, the scratch buffer now contains the incoming command. Keep in mind that
         the original buffer still contains the APDU header.
         Initialise our TLV reader
        tlvReader.init(scratch, (short)0, length);
         PRE-CONDITIONS
         PRE-CONDITION 1 - The 'COMMAND' constructed tag must be present
        if (!tlvReader.match(CONST_TAG_COMMAND)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
         Move into the constructed tag
        tlvReader.moveInto();
         PRE-CONDITION 2 - The mandatory 'OPERATION' tag must be present with length 1
        if (!tlvReader.match(CONST_TAG_OPERATION)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        byte operation = tlvReader.toByte();
         PRE-CONDITION 3 - The 'OPERATION' value must be set to the value CONST_OP_DATA or CONST_OP_KEY
        if (operation != CONST_OP_DATA && operation != CONST_OP_KEY) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
         Move to the next tag
        tlvReader.moveNext();
         PRE-CONDITION 4 - The 'ID' value must be present with length 1
        if (!tlvReader.match(CONST_TAG_ID)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        byte id = tlvReader.toByte();
         Move to the next tag
        tlvReader.moveNext();
         PRE-CONDITION 5 - The 'MODE CONTACT' value must be present with length 1
        if (!tlvReader.match(CONST_TAG_MODE_CONTACT)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        byte modeContact = tlvReader.toByte();
         Move to the next tag
        tlvReader.moveNext();
         PRE-CONDITION 6 - The 'MODE CONTACTLESS' value must be present with length 1
        if (!tlvReader.match(CONST_TAG_MODE_CONTACTLESS)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        byte modeContactless = tlvReader.toByte();
        byte keyMechanism = ID_ALG_DEFAULT;
        byte keyRole = PIVKeyObject.ROLE_NONE;
         Move to the next tag
        tlvReader.moveNext();
        if (CONST_OP_KEY == operation) {
             PRE-CONDITION 7a - If the operation is CONST_OP_KEY, then the 'KEY MECHANISM' tag
            					 must be present with length 1
            if (!tlvReader.match(CONST_TAG_KEY_MECHANISM)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
            if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
            keyMechanism = tlvReader.toByte();
             Move to the next tag
            tlvReader.moveNext();
             PRE-CONDITION 8a - If the operation is CONST_OP_KEY, then the 'KEY ROLE' tag
            					 must be present with length 1
            if (!tlvReader.match(CONST_TAG_KEY_ROLE)) ISOException.throwIt(ISO7816.SW_WRONG_DATA);
            if (tlvReader.getLength() != (short)1) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
            keyRole = tlvReader.toByte();
             PRE-CONDITION 9a - If 'OPERATION' is set to CONST_OP_KEY, the key referenced by the 'id' and
            					  'mechanism' values must not already exist in the key store
            if (cspPIV.selectKey(id, keyMechanism) != null) {
                ISOException.throwIt(ISO7816.SW_FILE_FULL);
            }
        } else { (CONST_OP_DATA == operation)
             PRE-CONDITION 7b - If 'OPERATION' is set to CONST_OP_DATA, the object referenced by 'id' value
             					 must not already exist in the data store
            PIVObject obj = firstDataObject;
            while (obj != null) {
                if (obj.getId() == id) ISOException.throwIt(ISO7816.SW_FILE_FULL);
                obj = obj.nextObject;
            }
        }
         EXECUTION STEPS
         STEP 1 - If the operation is a DATA OBJECT, add it to the data store
        if (operation == CONST_OP_DATA) {
            createDataObject(id, modeContact, modeContactless);
        } else {  (operation == CONST_OP_KEY)
            cspPIV.createKey(id, modeContact, modeContactless, keyMechanism, keyRole);
        }
    }
public void putDataAdmin ( byte [ ] buffer , short offset , short length ) { final byte CONST_TAG_COMMAND = ( byte ) 0x30 ; final byte CONST_TAG_OPERATION = ( byte ) 0x8A ; final byte CONST_TAG_ID = ( byte ) 0x8B ; final byte CONST_TAG_MODE_CONTACT = ( byte ) 0x8C ; final byte CONST_TAG_MODE_CONTACTLESS = ( byte ) 0x8D ; final byte CONST_TAG_KEY_MECHANISM = ( byte ) 0x8E ; final byte CONST_TAG_KEY_ROLE = ( byte ) 0x8F ; final byte CONST_OP_DATA = ( byte ) 0x01 ; final byte CONST_OP_KEY = ( byte ) 0x02 ; if ( ! cspPIV . checkAccessModeAdmin ( true ) ) { ISOException . throwIt ( ISO7816 . SW_SECURITY_STATUS_NOT_SATISFIED ) ; } length = chainBuffer . processIncomingAPDU ( buffer , offset , length , scratch , ( short ) 0 ) ; if ( length == 0 ) return ; tlvReader . init ( scratch , ( short ) 0 , length ) ; if ( ! tlvReader . match ( CONST_TAG_COMMAND ) ) ISOException . throwIt ( ISO7816 . SW_WRONG_DATA ) ; tlvReader . moveInto ( ) ; if ( ! tlvReader . match ( CONST_TAG_OPERATION ) ) ISOException . throwIt ( ISO7816 . SW_WRONG_DATA ) ; byte operation = tlvReader . toByte ( ) ; if ( operation != CONST_OP_DATA && operation != CONST_OP_KEY ) ISOException . throwIt ( ISO7816 . SW_WRONG_DATA ) ; tlvReader . moveNext ( ) ; if ( ! tlvReader . match ( CONST_TAG_ID ) ) ISOException . throwIt ( ISO7816 . SW_WRONG_DATA ) ; if ( tlvReader . getLength ( ) != ( short ) 1 ) ISOException . throwIt ( ISO7816 . SW_WRONG_LENGTH ) ; byte id = tlvReader . toByte ( ) ; tlvReader . moveNext ( ) ; if ( ! tlvReader . match ( CONST_TAG_MODE_CONTACT ) ) ISOException . throwIt ( ISO7816 . SW_WRONG_DATA ) ; if ( tlvReader . getLength ( ) != ( short ) 1 ) ISOException . throwIt ( ISO7816 . SW_WRONG_LENGTH ) ; byte modeContact = tlvReader . toByte ( ) ; tlvReader . moveNext ( ) ; if ( ! tlvReader . match ( CONST_TAG_MODE_CONTACTLESS ) ) ISOException . throwIt ( ISO7816 . SW_WRONG_DATA ) ; if ( tlvReader . getLength ( ) != ( short ) 1 ) ISOException . throwIt ( ISO7816 . SW_WRONG_LENGTH ) ; byte modeContactless = tlvReader . toByte ( ) ; byte keyMechanism = ID_ALG_DEFAULT ; byte keyRole = PIVKeyObject . ROLE_NONE ; tlvReader . moveNext ( ) ; if ( CONST_OP_KEY == operation ) { if ( ! tlvReader . match ( CONST_TAG_KEY_MECHANISM ) ) ISOException . throwIt ( ISO7816 . SW_WRONG_DATA ) ; if ( tlvReader . getLength ( ) != ( short ) 1 ) ISOException . throwIt ( ISO7816 . SW_WRONG_LENGTH ) ; keyMechanism = tlvReader . toByte ( ) ; tlvReader . moveNext ( ) ; if ( ! tlvReader . match ( CONST_TAG_KEY_ROLE ) ) ISOException . throwIt ( ISO7816 . SW_WRONG_DATA ) ; if ( tlvReader . getLength ( ) != ( short ) 1 ) ISOException . throwIt ( ISO7816 . SW_WRONG_LENGTH ) ; keyRole = tlvReader . toByte ( ) ; if ( cspPIV . selectKey ( id , keyMechanism ) != null ) { ISOException . throwIt ( ISO7816 . SW_FILE_FULL ) ; } } else { PIVObject obj = firstDataObject ; while ( obj != null ) { if ( obj . getId ( ) == id ) ISOException . throwIt ( ISO7816 . SW_FILE_FULL ) ; obj = obj . nextObject ; } } if ( operation == CONST_OP_DATA ) { createDataObject ( id , modeContact , modeContactless ) ; } else { cspPIV . createKey ( id , modeContact , modeContactless , keyMechanism , keyRole ) ; } }
This is the administrative equivalent for the PUT DATA card and is intended for
 use by Card Management Systems to generate the on-card file-system.
This is the administrative equivalent for the PUT DATA card and is intended for use by Card Management Systems to generate the on - card file - system .
// // SECURITY PRE-CONDITION // // The command must have been sent over SCP with CEnc+CMac // // COMMAND CHAIN HANDLING // // Pass the APDU to the chainBuffer instance first. It will return zero if there is store more // to of the chain to process, otherwise it will return the length of the large CDATA buffer // If the length is zero, just return so the caller can keep sending // If we got this far, the scratch buffer now contains the incoming command. Keep in mind that // the original buffer still contains the APDU header. // Initialise our TLV reader // // PRE-CONDITIONS // // PRE-CONDITION 1 - The 'COMMAND' constructed tag must be present // Move into the constructed tag // PRE-CONDITION 2 - The mandatory 'OPERATION' tag must be present with length 1 // PRE-CONDITION 3 - The 'OPERATION' value must be set to the value CONST_OP_DATA or CONST_OP_KEY // Move to the next tag // PRE-CONDITION 4 - The 'ID' value must be present with length 1 // Move to the next tag // PRE-CONDITION 5 - The 'MODE CONTACT' value must be present with length 1 // Move to the next tag // PRE-CONDITION 6 - The 'MODE CONTACTLESS' value must be present with length 1 // Move to the next tag // PRE-CONDITION 7a - If the operation is CONST_OP_KEY, then the 'KEY MECHANISM' tag //					 must be present with length 1 // Move to the next tag // PRE-CONDITION 8a - If the operation is CONST_OP_KEY, then the 'KEY ROLE' tag //					 must be present with length 1 // PRE-CONDITION 9a - If 'OPERATION' is set to CONST_OP_KEY, the key referenced by the 'id' and //					  'mechanism' values must not already exist in the key store //(CONST_OP_DATA == operation) // PRE-CONDITION 7b - If 'OPERATION' is set to CONST_OP_DATA, the object referenced by 'id' value // 					 must not already exist in the data store // // EXECUTION STEPS // // STEP 1 - If the operation is a DATA OBJECT, add it to the data store // (operation == CONST_OP_KEY)