javacard.framework.ISOException Java Examples

The following examples show how to use javacard.framework.ISOException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 7 votes vote down vote up
/**
 * Retrieves the Key object to be used w/ the specified key number, key type
 * (KEY_XX) and size. If exists, check it has the proper key type If not,
 * creates it.
 * 
 * @return Retrieved Key object or throws SW_UNATUTHORIZED,
 *         SW_OPERATION_NOT_ALLOWED
 */
private Key getKey(byte key_nb, byte key_type, short key_size) {
	
	if (eckeys[key_nb] == null) {
		// We have to create the Key
		eckeys[key_nb] = KeyBuilder.buildKey(key_type, key_size, false);
	} else {
		// Key already exists: check size & type
		/*
		 * TODO: As an option, we could just discard and recreate if not of
		 * the correct type, but creates trash objects
		 */
		if ((eckeys[key_nb].getSize() != key_size) || (eckeys[key_nb].getType() != key_type))
			ISOException.throwIt(SW_OPERATION_NOT_ALLOWED);
	}
	return eckeys[key_nb];
}
 
Example #2
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 6 votes vote down vote up
/**
 * This function returns the authentikey public key (uniquely derived from the Bip32 seed).
 * The function returns the x-coordinate of the authentikey, self-signed.
 * The authentikey full public key can be recovered from the signature.
 * 
 *  ins: 0x73
 *  p1: 0x00 
 *  p2: 0x00 
 *  data: none
 *  return: [coordx_size(2b) | coordx | sig_size(2b) | sig]
 */
private short getBIP32AuthentiKey(APDU apdu, byte[] buffer){
	// check that PIN[0] has been entered previously
	if (!pins[0].isValidated())
		ISOException.throwIt(SW_UNAUTHORIZED);
	
	// check whether the seed is initialized
	if (!bip32_seeded)
		ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED);
	
	// compute the partial authentikey public key...
       keyAgreement.init(bip32_authentikey);        
       short coordx_size= (short)32;
   	keyAgreement.generateSecret(Secp256k1.SECP256K1, Secp256k1.OFFSET_SECP256K1_G, (short) 65, buffer, (short)1); //pubkey in uncompressed form
	Util.setShort(buffer, (short)0, coordx_size);
       // self signed public key
       sigECDSA.init(bip32_authentikey, Signature.MODE_SIGN);
       short sign_size= sigECDSA.sign(buffer, (short)0, (short)(coordx_size+2), buffer, (short)(coordx_size+4));
       Util.setShort(buffer, (short)(coordx_size+2), sign_size);
       
       // return x-coordinate of public key+signature
       // the client can recover full public-key from the signature or
       // by guessing the compression value () and verifying the signature... 
       // buffer= [coordx_size(2) | coordx | sigsize(2) | sig]
       return (short)(coordx_size+sign_size+4);
}
 
Example #3
Source File: Bignat.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Copies content of {@code other} into this and set size of this to {@code other}. 
 * The size attribute (returned by length()) is updated. If {@code other}
 * is longer than maximum capacity of this, internal buffer is reallocated if enabled 
 * (ALLOW_RUNTIME_REALLOCATION), otherwise exception is thrown.
 * @param other 
 *            Bignat to clone into this object.
 */    
public void clone(Bignat other) { 
    // Reallocate array only if current array cannot store the other value and reallocation is enabled by ALLOW_RUNTIME_REALLOCATION
    if (this.max_size < other.length()) {
        // Reallocation necessary
        if (ALLOW_RUNTIME_REALLOCATION) {
            allocate_storage_array(other.length(), this.allocatorType);
        }
        else {
            ISOException.throwIt(ReturnCodes.SW_BIGNAT_REALLOCATIONNOTALLOWED);
        }
    }
    
    // copy value from other into proper place in this (this can be longer than other so rest of bytes wil be filled with 0)
    other.copy_to_buffer(this.value, (short) 0);
    if (this.max_size > other.length()) {
        Util.arrayFillNonAtomic(this.value, other.length(), (short) (this.max_size - other.length()), (byte) 0);
    }
    this.size = other.length();
}
 
Example #4
Source File: Bignat.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
* Copies {@code other} into this. No size requirements. If {@code other}
* has more digits then the superfluous leading digits of {@code other} are
* asserted to be zero. If this bignat has more digits than its leading
* digits are correctly initilized to zero. This function will not change size 
* attribute of this object.
* 
* @param other
*            Bignat to copy into this object.
*/
public void copy(Bignat other) {
    short this_start, other_start, len;
    if (this.size >= other.size) {
        this_start = (short) (this.size - other.size);
        other_start = 0;
        len = other.size;
    } else {
        this_start = 0;
        other_start = (short) (other.size - this.size);
        len = this.size;
        // Verify here that other have leading zeroes up to other_start
        for (short i = 0; i < other_start; i ++) {
            if (other.value[i] != 0) {
                ISOException.throwIt(ReturnCodes.SW_BIGNAT_INVALIDCOPYOTHER);
            }
        }
    }

    if (this_start > 0) {
        // if this bignat has more digits than its leading digits are initilized to zero
        Util.arrayFillNonAtomic(this.value, (short) 0, this_start, (byte) 0);
    }
    Util.arrayCopyNonAtomic(other.value, other_start, this.value, this_start, len);
}
 
Example #5
Source File: Bignat.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Calculates {@code res := base ** exp mod mod} using RSA engine. 
 * Requirements:
 * 1. Modulo must be either 521, 1024, 2048 or other lengths supported by RSA (see appendzeros() and mod() method)
 * 2. Base must have the same size as modulo (see prependzeros())
 * @param baseLen   length of base rounded to size of RSA engine
 * @param base      value of base (if size is not equal to baseLen then zeroes are appended)
 * @param exponent  array with exponent
 * @param exponentLen length of exponent
 * @param modulo    value of modulo 
 * @param resultArray array for the computed result
 * @param resultOffset start offset of resultArray
 */
private short n_mod_exp(short baseLen, Bignat base, byte[] exponent, short exponentLen, Bignat modulo, byte[] resultArray, short resultOffset) {
    // Verify if pre-allocated engine match the required values
    if (bnh.fnc_NmodE_pubKey.getSize() < (short) (modulo.length() * 8)) {
        // attempt to perform modulu with higher or smaller than supported length - try change constant MODULO_ENGINE_MAX_LENGTH
        ISOException.throwIt(ReturnCodes.SW_BIGNAT_MODULOTOOLARGE);
    }
    if (bnh.fnc_NmodE_pubKey.getSize() < (short) (base.length() * 8)) {
        ISOException.throwIt(ReturnCodes.SW_BIGNAT_MODULOTOOLARGE);
    }
    // Potential problem: we are changing key value for publicKey already used before with occ.bnHelper.modCipher. 
    // Simulator and potentially some cards fail to initialize this new value properly (probably assuming that same key object will always have same value)
    // Fix (if problem occure): generate new key object: RSAPublicKey publicKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, (short) (baseLen * 8), false);

    bnh.fnc_NmodE_pubKey.setExponent(exponent, (short) 0, exponentLen);
    bnh.lock(bnh.fnc_deep_resize_tmp);
    modulo.append_zeros(baseLen, bnh.fnc_deep_resize_tmp, (short) 0);
    bnh.fnc_NmodE_pubKey.setModulus(bnh.fnc_deep_resize_tmp, (short) 0, baseLen);
    bnh.fnc_NmodE_cipher.init(bnh.fnc_NmodE_pubKey, Cipher.MODE_DECRYPT);        
    base.prepend_zeros(baseLen, bnh.fnc_deep_resize_tmp, (short) 0);
    // BUGBUG: Check if input is not all zeroes (causes out-of-bound exception on some cards)
    short len = bnh.fnc_NmodE_cipher.doFinal(bnh.fnc_deep_resize_tmp, (short) 0, baseLen, resultArray, resultOffset); 
    bnh.unlock(bnh.fnc_deep_resize_tmp);
    return len;
}
 
Example #6
Source File: ObjectLocker.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Lock/reserve provided object for subsequent use. Used to protect corruption
 * of pre-allocated shared objects in different, potentially nested,
 * operations. Must be unlocked later on.
 *
 * @param objToLock array to be locked
 * @throws SW_ALREADYLOCKED if already locked (is already in use by
 * other operation)
 */
public void lock(Object objToLock) {
    if (!bLockingActive) {
        return;
    }
    // Find object to lock
    short i;
    for (i = 0; i < (short) lockedObjects.length; i += 2) {
        if (lockedObjects[i] != null && lockedObjects[i].equals(objToLock)) {
            lock(objToLock, i);
            break;
        }
    }
    // If reached here, required array was not found
    if (i == (short) lockedObjects.length) {
        ISOException.throwIt(ReturnCodes.SW_LOCK_OBJECT_NOT_FOUND);
    }
}
 
Example #7
Source File: ObjectLocker.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Register new object for lock guarding. 
 * @param objToLock object to be guarded
 * @return index to internal array where registered object is stored (if known, lock/unlock is faster)
 */
public short registerLock(Object objToLock) {
    short i;
    for (i = 0; i < (short) lockedObjects.length; i += 2) {
        if (lockedObjects[i] == null) {
            // Free slot found
            lockedObjects[i] = objToLock;
            lockedObjects[(short) (i + 1)] = null; // null means array is unlocked
            lockedObjectsPersistent[i] = objToLock; // Store same into persistent array as well
            lockedObjectsPersistent[(short) (i + 1)] = null; 
            return i; // Return index for potential speedup of locking
        }
    }
    ISOException.throwIt(ReturnCodes.SW_LOCK_NOFREESLOT);
    return -1;
}
 
Example #8
Source File: GaussKeyCard.java    From gauss-key-card with Apache License 2.0 6 votes vote down vote up
private void
processAuthenticate(APDU apdu)
{
	final byte[] buffer = apdu.getBuffer();
	final short incomingLength = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);

	if (incomingLength < (short)0x51) {
		ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
	}

	ecdh.generateSecret(buffer, ISO7816.OFFSET_CDATA, (short)65, buffer, (short)16);

	aes_key.setKey(buffer, (short)16);
	aes_ecb.init(aes_key, Cipher.MODE_ENCRYPT);

	// Generate the random salt.
	rng.generateData(buffer, OFFSET_CHALLENGE, (short)4);

	short len = aes_ecb.doFinal(buffer, OFFSET_CHALLENGE, (short)16, buffer, (short)0);
	final short le = apdu.setOutgoing();

	len = le > 0 ? (le > len ? len : le) : len;
	apdu.setOutgoingLength(len);
	apdu.sendBytes((short)0, len);
}
 
Example #9
Source File: NdefApplet.java    From openjavacard-ndef with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Access a file for reading
 *
 * This function serves to perform precondition checks
 * before actually operating on a file in a read operation.
 *
 * If this function succeeds then the given fileId was
 * valid, security access has been granted and reading
 * of data for this file is possible.
 *
 * @param fileId of the file to be read
 * @return data array of the file
 * @throws ISOException on error
 */
private byte[] accessFileForRead(short fileId) throws ISOException {
    byte[] file = null;
    // select relevant data
    if(fileId == FILEID_NDEF_CAPABILITIES) {
        file = capsFile;
    }
    if(fileId == FILEID_NDEF_DATA) {
        file = (byte[])refs[REF_DATA];
    }
    // check that we got anything
    if(file == null) {
        ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    }
    return file;
}
 
Example #10
Source File: ObjectLocker.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Check if provided object is logically locked
 * @param objToUnlock object to be checked
 * @return true of array is logically locked, false otherwise 
 */

public boolean isLocked(Object objToUnlock) {
    if (!bLockingActive) {
        return false;
    }
    // Find object to unlock
    short i;
    for (i = 0; i < (short) lockedObjects.length; i += 2) {
        if (lockedObjects[i] != null && lockedObjects[i].equals(objToUnlock)) {
            return lockedObjects[(short) (i + 1)] != null;
        }
    }
    // If reached here, required object was not found
    if (i == (short) lockedObjects.length) {
        ISOException.throwIt(ReturnCodes.SW_LOCK_OBJECT_NOT_FOUND);
    }
    return false;
}
 
Example #11
Source File: TransitApplet.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Verifies the PIN.
 * 
 * @param apdu
 *            The APDU
 */
private void verify(APDU apdu) {

    byte[] buffer = apdu.getBuffer();

    byte numBytes = buffer[ISO7816.OFFSET_LC];

    byte count = (byte) apdu.setIncomingAndReceive();

    if (numBytes != count) {
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    }

    // Verify PIN
    if (pin.check(buffer, ISO7816.OFFSET_CDATA, numBytes) == false) {
        ISOException.throwIt(SW_VERIFICATION_FAILED);
    }
}
 
Example #12
Source File: TransitApplet.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Generates the session key derivation data from the passed-in host
 * challenge and the card challenge.
 * 
 * @param buffer
 *            The APDU buffer
 */
private void generateKeyDerivationData(byte[] buffer) {
    byte numBytes = buffer[ISO7816.OFFSET_LC];

    if (numBytes < CHALLENGE_LENGTH) {
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    }

    // Derivation data: [[8-bytes host challenge], [8-bytes card challenge]]

    // Append host challenge (from buffer) to derivation data
    Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, keyDerivationData,
            (short) 0, CHALLENGE_LENGTH);
    // Append card challenge to derivation data
    Util.arrayCopy(cardChallenge, (short) 0, keyDerivationData,
            CHALLENGE_LENGTH, CHALLENGE_LENGTH);
}
 
Example #13
Source File: TransitApplet.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Checks the request message signature.
 * 
 * @param buffer
 *            The APDU buffer
 * @return true if the message signature is correct; false otherwise
 */
private boolean checkMAC(byte[] buffer) {
    byte numBytes = buffer[ISO7816.OFFSET_LC];

    if (numBytes <= MAC_LENGTH) {
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    }

    // Initialize signature with current session key for verification
    signature.init(sessionKey, Signature.MODE_VERIFY);
    // Verify request message signature
    return signature.verify(buffer, ISO7816.OFFSET_CDATA,
            (short) (numBytes - MAC_LENGTH), buffer,
            (short) (ISO7816.OFFSET_CDATA + numBytes - MAC_LENGTH),
     MAC_LENGTH);
}
 
Example #14
Source File: Bip32ObjectManager.java    From SatochipApplet with GNU Affero General Public License v3.0 6 votes vote down vote up
/**
 * Creates an object by reserving a fixed memory size for it.
 * Throws a SW_NO_MEMORY_LEFT exception if cannot allocate the memory.
 * 
 * @param src
 *            the source array to copy from
 * @param srcOff
 *            the offset for the source array
 *            
 * @return The memory base address for the object.
 */
public short createObject(byte[] src, short srcOff) {
	if (nb_elem_free == 0)
		ISOException.throwIt(SW_NO_MEMORY_LEFT);		
	
	short base=0;
	while (base<this.size) {
		if (Util.arrayCompare(this.ptr, base, this.empty, (short)0, this.size_id)==0){
			Util.arrayCopyNonAtomic(src, srcOff, this.ptr, base, this.size_elem);
			this.nb_elem_free--;
			this.nb_elem_used++;
			return base;
		}
		base+=this.size_elem;	
	}
	return NULL_OFFSET;//should not happen
}
 
Example #15
Source File: TransitApplet.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Gets/returns the balance.
 * 
 * Request Message: []
 * 
 * Response Message: [2-bytes Balance]
 * 
 * @param buffer
 *            The APDU buffer
 * @param messageOffset
 *            The offset of the request message content in the APDU buffer
 * @param messageLength
 *            The length of the request message content.
 * @return The offset at which content can be appended to the response
 *         message
 */
private short getBalance(byte[] buffer, short messageOffset,
        short messageLength) {

    // Check access authorization
    if (!pin.isValidated()) {
        ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
    }

    // Request Message: []

    if (messageLength != 0) {
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    }

    // Response Message: [2-bytes Balance]

    short offset = 0;

    // Append balance to response message
    offset = Util.setShort(buffer, offset, balance);

    return offset;
}
 
Example #16
Source File: NdefApplet.java    From openjavacard-ndef with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Access a file for reading
 *
 * This function serves to perform precondition checks
 * before actually operating on a file in a read operation.
 *
 * If this function succeeds then the given fileId was
 * valid, security access has been granted and reading
 * of data for this file is possible.
 *
 * @param fileId of the file to be read
 * @return data array of the file
 * @throws ISOException on error
 */
private byte[] accessFileForRead(short fileId) throws ISOException {
    byte[] file = null;
    byte access = FILE_ACCESS_NONE;
    // select relevant data
    if(fileId == FILEID_NDEF_CAPABILITIES) {
        file = capsFile;
        access = FILE_ACCESS_OPEN;
    }
    if(fileId == FILEID_NDEF_DATA) {
        file = dataFile;
        access = dataReadAccess;
    }
    // check that we got anything
    if(file == null) {
        ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    }
    // perform access checks
    if(!checkAccess(file, access)) {
        ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
    }
    return file;
}
 
Example #17
Source File: NdefApplet.java    From openjavacard-ndef with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Attempt to connect to the backend service
 */
private void connectService() {
    NdefService service = null;
    // get AID object for service
    AID aid = JCSystem.lookupAID(serviceAID, (short)0, (byte)serviceAID.length);
    if(aid != null) {
        // get service object
        Shareable share = JCSystem.getAppletShareableInterfaceObject(aid, serviceID);
        // cast the service object
        if(share instanceof NdefService) {
            service = (NdefService)share;
        }
    }
    // check that we got a valid object
    if(service == null) {
        ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    }
    // retrieve the data array
    byte[] data = service.getData();
    if(data == null) {
        ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    }
    // remember both references
    refs[REF_SERVICE] = service;
    refs[REF_DATA] = data;
}
 
Example #18
Source File: NdefApplet.java    From openjavacard-ndef with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Access a file for writing
 *
 * This function serves to perform precondition checks
 * before actually operating on a file in a write operation.
 *
 * If this function succeeds then the given fileId was
 * valid, security access has been granted and writing
 * of data for this file is possible.
 *
 * @param fileId of the file to be written
 * @return data array of the file
 * @throws ISOException on error
 */
private byte[] accessFileForWrite(short fileId) throws ISOException {
    byte[] file = null;
    byte access = FILE_ACCESS_NONE;
    // CC can not be written
    if(fileId == FILEID_NDEF_CAPABILITIES) {
        ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
    }
    // select relevant data
    if(fileId == FILEID_NDEF_DATA) {
        file = dataFile;
        access = dataWriteAccess;
    }
    // check that we got something
    if(file == null) {
        ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    }
    // perform access checks
    if(!checkAccess(file, access)) {
        ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
    }
    return file;
}
 
Example #19
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 6 votes vote down vote up
/**
 * This function returns a 2 byte bit mask of the available PINs that are currently in
 * use. Each set bit corresponds to an active PIN.
 * 
 *  ins: 0x48
 *  p1: 0x00
 *  p2: 0x00
 *  data: none
 *  return: [RFU(1b) | PIN_mask(1b)]
 */
private short ListPINs(APDU apdu, byte[] buffer) {
	// check that PIN[0] has been entered previously
	if (!pins[0].isValidated())
		ISOException.throwIt(SW_UNAUTHORIZED);
	
	// Checking P1 & P2
	if (buffer[ISO7816.OFFSET_P1] != (byte) 0x00)
		ISOException.throwIt(SW_INCORRECT_P1);
	if (buffer[ISO7816.OFFSET_P2] != (byte) 0x00)
		ISOException.throwIt(SW_INCORRECT_P2);
	byte expectedBytes = (byte) (buffer[ISO7816.OFFSET_LC]);
	if (expectedBytes != (short) 2)
		ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
	// Build the PIN bit mask
	short mask = (short) 0x00;
	short b;
	for (b = (short) 0; b < MAX_NUM_PINS; b++)
		if (pins[b] != null)
			mask |= (short) (((short) 0x01) << b);
	// Fill the buffer
	Util.setShort(buffer, (short) 0, mask);
	// Send response
	return (short)2;
}
 
Example #20
Source File: NdefApplet.java    From openjavacard-ndef with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Main constructor
 *
 * This will construct and initialize an instance
 * of this applet according to the provided app data.
 *
 * @param buf containing application data
 * @param off offset of app data in buf
 * @param len length of app data in buf
 */
protected NdefApplet(byte[] buf, short off, byte len) {
    // length of actual data file
    short dataLen = (short)(len + 2);
    // create transient variables
    vars = JCSystem.makeTransientShortArray(NUM_VARS, JCSystem.CLEAR_ON_DESELECT);
    // create capabilities files
    capsFile = makeCaps(dataLen);
    // create data file
    byte[] data = null;
    if (len > 0) {
        data = new byte[dataLen];
        // container size
        Util.setShort(data, (short) 0, len);
        // initial data
        Util.arrayCopyNonAtomic(buf, off, data, (short) 2, len);
    } else {
        ISOException.throwIt(ISO7816.SW_DATA_INVALID);
    }
    dataFile = data;
}
 
Example #21
Source File: GidsApplet.java    From GidsApplet with GNU General Public License v3.0 5 votes vote down vote up
/**
 * \brief Process the PUT DATA apdu (INS=DB).
 *
 * PUT DATA is currently used for private key import.
 *
 * \throw ISOException SW_SECURITY_STATUS_NOT_SATISFIED, SW_INCORRECT_P1P2
 */
private void processPutData(APDU apdu) throws ISOException {
    byte[] buf = apdu.getBuffer();
    byte p1 = buf[ISO7816.OFFSET_P1];
    byte p2 = buf[ISO7816.OFFSET_P2];

    if(p1 == (byte) 0x3F && p2 == (byte) 0xFF) {
        importPrivateKey(apdu);
    } else {
        fs.processPutData(apdu);
    }
}
 
Example #22
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 5 votes vote down vote up
/**
 * This function unblocks a PIN number using the unblock code specified in the
 * DATA portion. The P3 byte specifies the unblock code length. 
 * 
 * ins: 0x46
 * p1: PIN number (0x00-0x07)
 * p2: 0x00
 * data: [PUK] 
 * return: none (throws an exception in case of wrong PUK)
 */
private short UnblockPIN(APDU apdu, byte[] buffer) {
	byte pin_nb = buffer[ISO7816.OFFSET_P1];
	if ((pin_nb < 0) || (pin_nb >= MAX_NUM_PINS))
		ISOException.throwIt(SW_INCORRECT_P1);
	OwnerPIN pin = pins[pin_nb];
	OwnerPIN ublk_pin = ublk_pins[pin_nb];
	if (pin == null)
		ISOException.throwIt(SW_INCORRECT_P1);
	if (ublk_pin == null)
		ISOException.throwIt(SW_INTERNAL_ERROR);
	// If the PIN is not blocked, the call is inconsistent
	if (pin.getTriesRemaining() != 0)
		ISOException.throwIt(SW_OPERATION_NOT_ALLOWED);
	if (buffer[ISO7816.OFFSET_P2] != 0x00)
		ISOException.throwIt(SW_INCORRECT_P2);
	short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]);
	/*
	 * Here I suppose the PIN code is small enough to fit into the buffer
	 * TODO: Verify the assumption and eventually adjust code to support
	 * reading PIN in multiple read()s
	 */
	if (!CheckPINPolicy(buffer, ISO7816.OFFSET_CDATA, (byte) bytesLeft))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	byte triesRemaining	= ublk_pin.getTriesRemaining();
	if (triesRemaining == (byte) 0x00)
		ISOException.throwIt(SW_IDENTITY_BLOCKED);
	if (!ublk_pin.check(buffer, ISO7816.OFFSET_CDATA, (byte) bytesLeft))
		ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining - 1));
	
	pin.resetAndUnblock();
	
	return (short)0;
}
 
Example #23
Source File: File.java    From GidsApplet with GNU General Public License v3.0 5 votes vote down vote up
public void CheckPermission(GidsPINManager pinManager, byte flag_operation) {
    if (state == STATE_CREATION) {
        if (this instanceof ApplicationFile) {
            // every operation is allowed on the application on the creation state
            return;
        }
        if (this instanceof ElementaryFile) {
            // only a transition to operational state is allowed
            if (flag_operation != ACL_OP_EF_ACTIVATE) {
                ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
            }
        }
        if (this instanceof DedicatedFile) {
            // only a transition to operational state is allowed
            if (flag_operation != ACL_OP_DF_ACTIVATE) {
                ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
            }
        }
    } else if (state == STATE_TERMINATED) {
        if (this instanceof ApplicationFile) {
            // every operation is denied on the application on the termination state
            ISOException.throwIt(ErrorCode.SW_TERMINATION_STATE);
        }
        if (this instanceof ElementaryFile) {
            // only a transition to operational state is allowed
            if (flag_operation != ACL_OP_EF_DELETE) {
                ISOException.throwIt(ErrorCode.SW_TERMINATION_STATE);
            }
        }
        if (this instanceof DedicatedFile) {
            // only a transition to operational state is allowed
            if (flag_operation != ACL_OP_DF_DELETE_SELF) {
                ISOException.throwIt(ErrorCode.SW_TERMINATION_STATE);
            }
        }
    }
    CheckACLRequirements(pinManager, flag_operation);
}
 
Example #24
Source File: TransmitManager.java    From GidsApplet with GNU General Public License v3.0 5 votes vote down vote up
public short doChainingOrExtAPDUFlash(APDU apdu) throws ISOException {
    // allocate flash buffer only when needed - it can remain for the rest of the card life
    if (flash_buf == null)
    {
        try {
            flash_buf = new byte[FLASH_BUF_SIZE];
        } catch(SystemException e) {
            if(e.getReason() == SystemException.NO_RESOURCE) {
                ISOException.throwIt(ISO7816.SW_FILE_FULL);
            }
            ISOException.throwIt(ISO7816.SW_UNKNOWN);
        }
    }
    return doChainingOrExtAPDUWithBuffer(apdu, flash_buf, FLASH_BUF_SIZE);
}
 
Example #25
Source File: Bignat.java    From JCMathLib with MIT License 5 votes vote down vote up
/**
 * Sets internal size of Bignat. Previous value are kept so value is either non-destructively trimmed or enlarged. 
 * @param newSize new size of Bignat. Must be in range of [0, max_size] where max_size was provided during object creation
 */
public void set_size(short newSize) {
    if (newSize < 0 || newSize > max_size) {
        ISOException.throwIt(ReturnCodes.SW_BIGNAT_RESIZETOLONGER);
    }
    else {
        this.size = newSize;
    }
}
 
Example #26
Source File: HmacSha512.java    From SatochipApplet with GNU Affero General Public License v3.0 5 votes vote down vote up
public static void init(byte[] tmp){
	data= tmp;
	try {
		sha512 = MessageDigest.getInstance(MessageDigest.ALG_SHA_512, false); 
	} catch (CryptoException e) {
		ISOException.throwIt(CardEdge.SW_UNSUPPORTED_FEATURE); // unsupported feature => use a more recent card!
	}
}
 
Example #27
Source File: HmacSha512.java    From SatochipApplet with GNU Affero General Public License v3.0 5 votes vote down vote up
public static short computeHmacSha512(byte[] key, short key_offset, short key_length, 
		byte[] message, short message_offset, short message_length,
		byte[] mac, short mac_offset){
	
	if (key_length>BLOCKSIZE || key_length<0){
		ISOException.throwIt(CardEdge.SW_HMAC_UNSUPPORTED_KEYSIZE); // don't accept keys bigger than block size 
	}
	if (message_length>HASHSIZE || message_length<0){
		ISOException.throwIt(CardEdge.SW_HMAC_UNSUPPORTED_MSGSIZE); // don't accept message bigger than block size (should be sufficient for BIP32)
	}
	
	// compute inner hash
	for (short i=0; i<key_length; i++){
		data[i]= (byte) (key[(short)(key_offset+i)] ^ (0x36));
	}
	Util.arrayFillNonAtomic(data, key_length, (short)(BLOCKSIZE-key_length), (byte)0x36);		
	Util.arrayCopyNonAtomic(message, message_offset, data, BLOCKSIZE, message_length);
	sha512.reset();
	sha512.doFinal(data, (short)0, (short)(BLOCKSIZE+message_length), data, BLOCKSIZE); // copy hash result to data buffer!
	
	// compute outer hash
	for (short i=0; i<key_length; i++){
		data[i]= (byte) (key[(short)(key_offset+i)] ^ (0x5c));
	}
	Util.arrayFillNonAtomic(data, key_length, (short)(BLOCKSIZE-key_length), (byte)0x5c);
	// previous hash already copied to correct offset in data
	sha512.reset();
	sha512.doFinal(data, (short)0, (short)(BLOCKSIZE+HASHSIZE), mac, mac_offset);
	
	return HASHSIZE;
}
 
Example #28
Source File: NdefApplet.java    From openjavacard-ndef with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Process an APDU
 *
 * This is the outer layer of our APDU dispatch.
 *
 * It deals with the CLA and INS of the APDU,
 * leaving the rest to an INS-specific function.
 *
 * @param apdu to be processed
 * @throws ISOException on error
 */
public final void process(APDU apdu) throws ISOException {
    byte[] buffer = apdu.getBuffer();
    byte ins = buffer[ISO7816.OFFSET_INS];

    // handle selection of the applet
    if(selectingApplet()) {
        vars[VAR_SELECTED_FILE] = FILEID_NONE;
        return;
    }

    // secure messaging is not supported
    if(apdu.isSecureMessagingCLA()) {
        ISOException.throwIt(ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED);
    }

    // process commands to the applet
    if(apdu.isISOInterindustryCLA()) {
        if (ins == INS_SELECT) {
            processSelect(apdu);
        } else if (ins == INS_READ_BINARY) {
            processReadBinary(apdu);
        } else if (ins == INS_UPDATE_BINARY) {
            ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
        } else {
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    } else {
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }
}
 
Example #29
Source File: GidsPINManager.java    From GidsApplet with GNU General Public License v3.0 5 votes vote down vote up
/**
 * \brief return information regarding the PIN
 */
public void returnPINStatus(APDU apdu, short id) {
    byte[] buf = apdu.getBuffer();
    GidsPIN pin = null;
    switch(id) {
    default:
        ISOException.throwIt(ErrorCode.SW_REFERENCE_DATA_NOT_FOUND);
        break;
    case (short) 0x7F71:
    case (short) 0x7F72:
        pin = pin_pin;
        break;
    }

    Util.setShort(buf, (short) 0, id);
    buf[2] = (byte) 0x06;
    buf[3] = (byte) 0x97;
    buf[4] = (byte) 0x01;
    buf[5] = pin.getTriesRemaining();
    buf[6] = (byte) 0x93;
    buf[7] = (byte) 0x01;
    buf[8] = pin.getTryLimit();
    apdu.setOutgoing();
    apdu.setOutgoingLength((short)9);
    apdu.sendBytes((short) 0, (short) 9);

}
 
Example #30
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 5 votes vote down vote up
/**
 * This function allows to reset the 2FA key and disable 2FA.
 * Once activated, 2FA can only be deactivated when the seed is reset and all eckeys cleared.
 *  
 *  ins: 0x78
 *  p1: 0x00
 *  p2: 0x00
 *  data: [hmacsha1_key(20b)]
 *  return: (none)
 */
private short reset2FAKey(APDU apdu, byte[] buffer){
	// check that PIN[0] has been entered previously
	if (!pins[0].isValidated())
		ISOException.throwIt(SW_UNAUTHORIZED);
	
	// check length
	short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]);
	if (bytesLeft < (short)20)
		ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
	
	// reset 2FA can only be done if all private keys are cleared
	if (!needs_2FA)
		ISOException.throwIt(SW_2FA_UNINITIALIZED_KEY);
	if (bip32_seeded)
		ISOException.throwIt(SW_BIP32_INITIALIZED_SEED);
	if (eckeys_flag != 0x0000)
		ISOException.throwIt(SW_ECKEYS_INITIALIZED_KEY);
	
	// compute hmac(2FA_ID) and compare with value provided 
	// hmac of 64-bytes msg: (id_2FA(20b) | 44 bytes 0xAA-padding)
	short offset= ISO7816.OFFSET_CDATA;
	Util.arrayFillNonAtomic(recvBuffer, (short)0, (short)64, (byte)0xAA);
	Util.arrayCopyNonAtomic(data2FA, OFFSET_2FA_ID, recvBuffer, (short)0, (short)20);
	HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64);
	if (Util.arrayCompare(buffer, offset, recvBuffer, (short)64, (short)20)!=0)
		ISOException.throwIt(SW_SIGNATURE_INVALID);
	
	// reset flag and data
       needs_2FA= false;	
       key_2FA.clearKey();
       Util.arrayFillNonAtomic(data2FA, (short)0, OFFSET_2FA_SIZE, (byte)0x00);      
       
       return (short)0;
}