javacard.framework.OwnerPIN Java Examples

The following examples show how to use javacard.framework.OwnerPIN. 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 5 votes vote down vote up
/** 
 * This function creates a PIN with parameters specified by the P1, P2 and DATA
 * values. P2 specifies the maximum number of consecutive unsuccessful
 * verifications before the PIN blocks. PIN can be created only if one of the logged identities
 * allows it. 
 * 
 * ins: 0x40
 * p1: PIN number (0x00-0x07)
 * p2: max attempt number
 * data: [PIN_size(1b) | PIN | UBLK_size(1b) | UBLK] 
 * return: none
 */
private short CreatePIN(APDU apdu, byte[] buffer) {
	// check that PIN[0] has been entered previously
	if (!pins[0].isValidated())
		ISOException.throwIt(SW_UNAUTHORIZED);
	
	byte pin_nb = buffer[ISO7816.OFFSET_P1];
	byte num_tries = buffer[ISO7816.OFFSET_P2];
	
	if ((pin_nb < 0) || (pin_nb >= MAX_NUM_PINS) || (pins[pin_nb] != null))
		ISOException.throwIt(SW_INCORRECT_P1);
	/* Allow pin lengths > 127 (useful at all ?) */
	short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]);
	// At least 1 character for PIN and 1 for unblock code (+ lengths)
	if (bytesLeft < 4)
		ISOException.throwIt(SW_INVALID_PARAMETER);
	byte pin_size = buffer[ISO7816.OFFSET_CDATA];
	if (bytesLeft < (short) (1 + pin_size + 1))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	if (!CheckPINPolicy(buffer, (short) (ISO7816.OFFSET_CDATA + 1), pin_size))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	byte ucode_size = buffer[(short) (ISO7816.OFFSET_CDATA + 1 + pin_size)];
	if (bytesLeft != (short) (1 + pin_size + 1 + ucode_size))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	if (!CheckPINPolicy(buffer, (short) (ISO7816.OFFSET_CDATA + 1 + pin_size + 1), ucode_size))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	pins[pin_nb] = new OwnerPIN(num_tries, PIN_MAX_SIZE);
	pins[pin_nb].update(buffer, (short) (ISO7816.OFFSET_CDATA + 1), pin_size);
	ublk_pins[pin_nb] = new OwnerPIN((byte) 3, PIN_MAX_SIZE);
	// Recycle variable pin_size
	pin_size = (byte) (ISO7816.OFFSET_CDATA + 1 + pin_size + 1);
	ublk_pins[pin_nb].update(buffer, pin_size, ucode_size);
	
	return (short)0;
}
 
Example #2
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 5 votes vote down vote up
/** 
 * This function verifies a PIN number sent by the DATA portion. The length of
 * this PIN is specified by the value contained in P3.
 * Multiple consecutive unsuccessful PIN verifications will block the PIN. If a PIN
 * blocks, then an UnblockPIN command can be issued.
 * 
 * ins: 0x42
 * p1: PIN number (0x00-0x07)
 * p2: 0x00
 * data: [PIN] 
 * return: none (throws an exception in case of wrong PIN)
 */
private short VerifyPIN(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];
	if (pin == null)
		ISOException.throwIt(SW_INCORRECT_P1);
	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 enter in 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	= pin.getTriesRemaining();
	if (triesRemaining == (byte) 0x00)
		ISOException.throwIt(SW_IDENTITY_BLOCKED);
	if (!pin.check(buffer, (short) ISO7816.OFFSET_CDATA, (byte) bytesLeft)) {
		LogoutIdentity(pin_nb);
		ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining - 1));
	}
	
	// Actually register that PIN has been successfully verified.
	logged_ids |= (short) (0x0001 << pin_nb);
	
	return (short)0;
}
 
Example #3
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 #4
Source File: LedgerWalletApplet.java    From ledger-javacard with GNU Affero General Public License v3.0 5 votes vote down vote up
public LedgerWalletApplet(byte[] parameters, short parametersOffset, byte parametersLength) {
    BCDUtils.init();
    TC.init();
    Crypto.init();
    Transaction.init();
    Bip32Cache.init();
    Keycard.init();
    limits = new byte[LIMIT_LAST];
    scratch256 = JCSystem.makeTransientByteArray((short)256, JCSystem.CLEAR_ON_DESELECT);
    transactionPin = new OwnerPIN(TRANSACTION_PIN_ATTEMPTS, TRANSACTION_PIN_SIZE);
    walletPin = new OwnerPIN(WALLET_PIN_ATTEMPTS, WALLET_PIN_SIZE);
    secondaryPin = new OwnerPIN(SECONDARY_PIN_ATTEMPTS, SECONDARY_PIN_SIZE);
    masterDerived = new byte[64];
    chipKey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    trustedInputKey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    developerKey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    try {
        pairingKey = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_256, false);
    }
    catch(Exception e) {
    }
    reset();
    if (parametersLength != 0) {
        attestationPrivate = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, KeyBuilder.LENGTH_EC_FP_256, false);
        attestationPublic = new byte[65];
        Secp256k1.setCommonCurveParameters(attestationPrivate);
        attestationPrivate.setS(parameters, parametersOffset, (short)32);
        parametersOffset += (short)32;
        attestationSignature = new byte[parameters[(short)(parametersOffset + 1)] + 2];
        Util.arrayCopy(parameters, parametersOffset, attestationSignature, (short)0, (short)attestationSignature.length);
    }
}
 
Example #5
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/** 
 * This function changes a PIN code. The DATA portion contains both the old and
 * the new PIN codes. 
 * 
 * ins: 0x44
 * p1: PIN number (0x00-0x07)
 * p2: 0x00
 * data: [PIN_size(1b) | old_PIN | PIN_size(1b) | new_PIN ] 
 * return: none (throws an exception in case of wrong PIN)
 */
private short ChangePIN(APDU apdu, byte[] buffer) {
	/*
	 * Here I suppose the PIN code is small enough that 2 of them enter in
	 * the buffer TODO: Verify the assumption and eventually adjust code to
	 * support reading PINs in multiple read()s
	 */
	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];
	if (pin == null)
		ISOException.throwIt(SW_INCORRECT_P1);
	if (buffer[ISO7816.OFFSET_P2] != (byte) 0x00)
		ISOException.throwIt(SW_INCORRECT_P2);
	short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]);
	// At least 1 character for each PIN code
	if (bytesLeft < 4)
		ISOException.throwIt(SW_INVALID_PARAMETER);
	byte pin_size = buffer[ISO7816.OFFSET_CDATA];
	if (bytesLeft < (short) (1 + pin_size + 1))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	if (!CheckPINPolicy(buffer, (short) (ISO7816.OFFSET_CDATA + 1), pin_size))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	byte new_pin_size = buffer[(short) (ISO7816.OFFSET_CDATA + 1 + pin_size)];
	if (bytesLeft < (short) (1 + pin_size + 1 + new_pin_size))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	if (!CheckPINPolicy(buffer, (short) (ISO7816.OFFSET_CDATA + 1 + pin_size + 1), new_pin_size))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	
	byte triesRemaining	= pin.getTriesRemaining();
	if (triesRemaining == (byte) 0x00)
		ISOException.throwIt(SW_IDENTITY_BLOCKED);
	if (!pin.check(buffer, (short) (ISO7816.OFFSET_CDATA + 1), pin_size)) {
		LogoutIdentity(pin_nb);
		ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining - 1));
	}
	
	pin.update(buffer, (short) (ISO7816.OFFSET_CDATA + 1 + pin_size + 1), new_pin_size);
	// JC specifies this resets the validated flag. So we do.
	logged_ids &= (short) ((short) 0xFFFF ^ (0x01 << pin_nb));
	
	return (short)0;
}
 
Example #6
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * This function resets the Bip32 seed and all derived keys: the master key, chain code, authentikey 
 * and the 32-bit AES key that is used to encrypt/decrypt Bip32 object stored in secure memory.
 * If 2FA is enabled, then a hmac code must be provided, based on the 4-byte counter-2FA.
 *  
 *  ins: 0x77
 *  p1: PIN_size 
 *  p2: 0x00
 *  data: [PIN | optional-hmac(20b)]
 *  return: (none)
 */
private short resetBIP32Seed(APDU apdu, byte[] buffer){
	
	short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]);
	
	// check provided PIN
	byte pin_size= buffer[ISO7816.OFFSET_P1];
	OwnerPIN pin = pins[(byte)0x00];
	if (bytesLeft < pin_size)
		ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
	if (!CheckPINPolicy(buffer, ISO7816.OFFSET_CDATA, pin_size))
		ISOException.throwIt(SW_INVALID_PARAMETER);
	
	byte triesRemaining	= pin.getTriesRemaining();
	if (triesRemaining == (byte) 0x00)
		ISOException.throwIt(SW_IDENTITY_BLOCKED);
	if (!pin.check(buffer, (short) ISO7816.OFFSET_CDATA, (byte) pin_size)) {
		LogoutIdentity((byte)0x00);
		ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining - 1));
	}
	
	// check if seeded
	if (!bip32_seeded)
		ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED);
	
	// check 2FA if required
	if (needs_2FA){
		short offset= Util.makeShort((byte)0, ISO7816.OFFSET_CDATA);
		offset+=pin_size;
		bytesLeft-= pin_size;
		if (bytesLeft < (short)20)
			ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
		
		// compute hmac(counter_2FA) and compare with value provided 
		// hmac of 64-bytes msg: ( authentikey-coordx(32b) | 32bytes 0xFF-padding)
		Util.arrayFillNonAtomic(recvBuffer, (short)0, (short)64, (byte)0xFF);
		Util.arrayCopyNonAtomic(authentikey_pubkey, (short)0x01, recvBuffer, (short)0, BIP32_KEY_SIZE);
		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 memory cache, bip32 flag and all data!
	bip32_om.reset();
	bip32_seeded= false;
	bip32_masterkey.clearKey(); 
	bip32_masterchaincode.clearKey();
	bip32_encryptkey.clearKey();
	bip32_authentikey.clearKey();
	Secp256k1.setCommonCurveParameters(bip32_authentikey);// keep public params!
	Util.arrayFillNonAtomic(authentikey_pubkey, (short)0, (short)(2*BIP32_KEY_SIZE+1), (byte)0x00);
	LogOutAll();
	return (short)0;
}
 
Example #7
Source File: Gpg.java    From OpenPGP-Card with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Only this class's install method should create the applet object.
 */
protected Gpg(byte[] parameters, short offset, byte length) {
  pinLength = new byte[3];
  pins = new OwnerPIN[3];
  pins[PIN_INDEX_PW1] = new OwnerPIN(MAX_TRIES_PIN1, MAX_PIN_LENGTH);
  pins[PIN_INDEX_PW1].update(defaultPIN, (short) 0, MIN_PIN1_LENGTH);
  pinLength[PIN_INDEX_PW1] = MIN_PIN1_LENGTH;
  pins[PIN_INDEX_PW3] = new OwnerPIN(MAX_TRIES_PIN3, MAX_PIN_LENGTH);
  pins[PIN_INDEX_PW3].update(defaultPIN, (short) 0, MIN_PIN3_LENGTH);
  pinLength[PIN_INDEX_PW3] = MIN_PIN3_LENGTH;
  // The resetting code is disabled by default.
  pins[PIN_INDEX_RC] = new OwnerPIN(MAX_TRIES_RC, MAX_PIN_LENGTH);
  pinLength[PIN_INDEX_RC] = 0;
  pinSubmitted = JCSystem.makeTransientBooleanArray((short) 2, JCSystem.CLEAR_ON_DESELECT);

  commandChainingBuffer =
      JCSystem.makeTransientByteArray((short) (TEMP_PUT_KEY_ACCUMULATOR + RSA_KEY_LENGTH_BYTES),
                                      JCSystem.CLEAR_ON_DESELECT);

  privateDO1 = new byte[255];
  privateDO2 = new byte[255];
  privateDO3 = new byte[255];
  privateDO4 = new byte[255];

  loginData = new byte[(short) 255];
  url = new byte[(short) 255];
  name = new byte[(short) 40];
  language = new byte[(short) 9];
  sex = new byte[(short) 1];
  fingerprints = new byte[(short) 60];
  caFingerprints = new byte[(short) 60];
  generationDates = new byte[(short) 12];
  signatureCounter = new byte[(short) 3];
  pinValidForMultipleSignatures = (byte) 0;

  signatureKey = new KeyPair(KeyPair.ALG_RSA_CRT, (short) 2048);
  confidentialityKey = new KeyPair(KeyPair.ALG_RSA_CRT, (short) 2048);
  authenticationKey = new KeyPair(KeyPair.ALG_RSA_CRT, (short) 2048);
  cipherRSA = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
  randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);

  register();
}