All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javacard.framework.OwnerPIN Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2011 Licel LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package javacard.framework;

/**
 * This class represents an Owner PIN, implements Personal Identification Number
 * functionality as defined in the PIN interface, and
 * provides the ability to update the PIN and thus owner functionality.
 * 

* The implementation of this class must protect against attacks based on program * flow prediction. In addition, even if a transaction is in progress, update of * internal state, such as the try counter, the validated flag, and the blocking state, * shall not participate in the transaction during PIN presentation. *

* If an implementation of this class creates transient arrays, it must ensure that they are * CLEAR_ON_RESET transient objects. *

* The protected methods getValidatedFlag and * setValidatedFlag allow a subclass * of this class to optimize the storage for the validated boolean state. *

* Some methods of instances of this class are only suitable for sharing when there exists * a trust relationship among the applets. A typical shared usage would use * a proxy PIN interface which extends both the PIN interface and * the Shareable interface and re-declares the methods of the PIN interface. *

* Any of the methods of the OwnerPIN may be called with a transaction in * progress. None of the methods of OwnerPIN class initiate or alter the state * of the transaction if one is in progress. * */ public class OwnerPIN implements PIN { private static final byte VALIDATED = 0; private static final byte NUMFLAGS = 1; private byte tryLimit; private byte maxPINSize; private byte pinValue[]; private byte pinSize; // CHECK !!! Use transient array with size 1 element for store validation state private boolean flags[]; // CHECK !!! Use transient array with size 1 element for store tries counter private byte triesLeft[]; /** * Constructor. Allocates a new PIN instance with validated flag * set to false * @param tryLimit the maximum number of times an incorrect PIN can be presented. tryLimit must be >=1 * @param maxPINSize the maximum allowed PIN size. maxPINSize must be >=1 * @throws PINException with the following reason codes: *

    *
  • PINException.ILLEGAL_VALUE if tryLimit parameter is less than 1. *
  • PINException.ILLEGAL_VALUE if maxPINSize parameter is less than 1. *
*/ public OwnerPIN(byte tryLimit, byte maxPINSize) throws PINException { if (tryLimit < 1 || maxPINSize < 1) { PINException.throwIt(PINException.ILLEGAL_VALUE); } pinValue = new byte[maxPINSize]; pinSize = maxPINSize; this.maxPINSize = maxPINSize; this.tryLimit = tryLimit; triesLeft = new byte[1]; resetTriesRemaining(); flags = JCSystem.makeTransientBooleanArray((short) 1, JCSystem.CLEAR_ON_RESET); setValidatedFlag(false); } /** * This protected method returns the validated flag. * This method is intended for subclass of this OwnerPIN to access or * override the internal PIN state of the OwnerPIN. * @return the boolean state of the PIN validated flag */ protected boolean getValidatedFlag() { return flags[0]; } /** * This protected method sets the value of the validated flag. * This method is intended for subclass of this OwnerPIN to control or * override the internal PIN state of the OwnerPIN. * @param value the new value for the validated flag */ protected void setValidatedFlag(boolean value) { flags[0] = value; } /** * !!! CHECK * This internal method resets tries counter */ private void resetTriesRemaining() { Util.arrayFillNonAtomic(triesLeft, (short) 0, (short) 1, tryLimit); } /** * !!! CHECK * This internal method decrement tries counter */ private void decrementTriesRemaining() { Util.arrayFillNonAtomic(triesLeft, (short) 0, (short) 1, (byte) (triesLeft[0] - 1)); } /** * Returns the number of times remaining that an incorrect PIN can * be presented before the PIN is blocked. * @return the number of times remaining */ public byte getTriesRemaining() { return triesLeft[0]; } /** * Compares pin against the PIN value. If they match and the * PIN is not blocked, it sets the validated flag * and resets the try counter to its maximum. If it does not match, * it decrements the try counter and, if the counter has reached * zero, blocks the PIN. Even if a transaction is in progress, update of * internal state - the try counter, the validated flag, and the blocking state, * shall not participate in the transaction. *

* Note:

    *
  • If NullPointerException or ArrayIndexOutOfBoundsException is * thrown, the validated flag must be set to false, the try counter must be decremented * and, the PIN blocked if the counter reaches zero. *
  • If offset or length parameter * is negative an ArrayIndexOutOfBoundsException exception is thrown. *
  • If offset+length is greater than pin.length, the length * of the pin array, an ArrayIndexOutOfBoundsException exception is thrown. *
  • If pin parameter is null * a NullPointerException exception is thrown.
* @param pin the byte array containing the PIN value being checked * @param offset the starting offset in the pin array * @param length the length of pin * @return true if the PIN value matches; false otherwise * @throws ArrayIndexOutOfBoundsException if the check operation would cause access of data outside array bounds. * @throws NullPointerException if pin is null */ public boolean check(byte pin[], short offset, byte length) throws ArrayIndexOutOfBoundsException, NullPointerException { boolean noMoreTries = false; setValidatedFlag(false); if (getTriesRemaining() == 0) { noMoreTries = true; } else { decrementTriesRemaining(); } if (length > 0) { byte tester = pin[(short) ((offset + length) - 1)]; if (length != pinSize || noMoreTries) { return false; } } if (Util.arrayCompare(pin, offset, pinValue, (short) 0, length) == 0 && length == pinSize) { setValidatedFlag(true); resetTriesRemaining(); return true; } else { return false; } } /** * Returns true if a valid PIN has been presented since the last * card reset or last call to reset(). * @return true if validated; false otherwise */ public boolean isValidated() { return getValidatedFlag(); } /** * If the validated flag is set, this method resets the validated flag and * resets the PIN try counter to the value of the PIN try limit. * Even if a transaction is in progress, update of * internal state - the try counter, the validated flag, and the blocking state, * shall not participate in the transaction. * If the validated flag is not set, this method does nothing. */ public void reset() { if (isValidated()) { resetAndUnblock(); } } /** * This method sets a new value for the PIN and resets the PIN try * counter to the value of the PIN try limit. It also resets the validated flag.

* This method copies the input pin parameter into an internal representation. If a transaction is * in progress, the new pin and try counter update must be conditional i.e * the copy operation must use the transaction facility. * @param pin the byte array containing the new PIN value * @param offset the starting offset in the pin array * @param length he length of the new PIN * @throws PINException with the following reason codes: *

    *
  • PINException.ILLEGAL_VALUE if length is greater than configured maximum PIN size. *
*/ public void update(byte pin[], short offset, byte length) throws PINException { if (length > maxPINSize) { PINException.throwIt(PINException.ILLEGAL_VALUE); } Util.arrayCopy(pin, offset, pinValue, (short) 0, length); pinSize = length; triesLeft[0] = tryLimit; setValidatedFlag(false); } /** * This method resets the validated flag and * resets the PIN try counter to the value of the PIN try limit. * Even if a transaction is in progress, update of * internal state - the try counter, the validated flag, and the blocking state, * shall not participate in the transaction. * This method is used by the owner to re-enable the blocked PIN. */ public void resetAndUnblock() { resetTriesRemaining(); setValidatedFlag(false); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy