package de.persosim.simulator.cardobjects; import de.persosim.simulator.exception.AccessDeniedException; import de.persosim.simulator.seccondition.OrSecCondition; import de.persosim.simulator.seccondition.SecCondition; /** * This class extends a {@link PasswordAuthObject} by functionality which makes * it possible to change the PIN after creation. * XXX why not included this functionality in {@link PasswordAuthObject} (where it can be restricted by access rights)? * * @author slutters * */ public class ChangeablePasswordAuthObject extends PasswordAuthObject { protected int minLengthOfPasswordInBytes; protected int maxLengthOfPasswordInBytes; private SecCondition pinManagementCondition; protected SecCondition changePinCondition; public ChangeablePasswordAuthObject(AuthObjectIdentifier identifier, byte[] password, String passwordName, int minLengthOfPasswordInBytes, int maxLengthOfPasswordInBytes, SecCondition pinManagementCondition, SecCondition changePinCondition) { super(identifier, password, passwordName); if(minLengthOfPasswordInBytes < 0) {throw new IllegalArgumentException("minimum required length for " + passwordName + " in bytes must be >= 0");} if(maxLengthOfPasswordInBytes < minLengthOfPasswordInBytes) {throw new IllegalArgumentException("maximum required length for " + passwordName + " in bytes must be >= minimum required length");} if(password.length < minLengthOfPasswordInBytes) {throw new IllegalArgumentException(passwordName + " must be at least " + minLengthOfPasswordInBytes + " bytes long but is only " + password.length + " bytes long");} if(password.length > maxLengthOfPasswordInBytes) {throw new IllegalArgumentException(passwordName + " must be at most " + maxLengthOfPasswordInBytes + " bytes long but is " + password.length + " bytes long");} this.minLengthOfPasswordInBytes = minLengthOfPasswordInBytes; this.maxLengthOfPasswordInBytes = maxLengthOfPasswordInBytes; this.pinManagementCondition = pinManagementCondition; this.changePinCondition = changePinCondition; } public void setPassword(byte[] newPassword) throws AccessDeniedException { if(!getLifeCycleState().equals(Iso7816LifeCycleState.OPERATIONAL_ACTIVATED)) {throw new IllegalStateException(passwordName + " must be in state operational activated");} if(newPassword == null) {throw new IllegalArgumentException("new " + passwordName + " must not be null");} if(newPassword.length < minLengthOfPasswordInBytes) {throw new IllegalArgumentException("new " + passwordName + " must be at least " + minLengthOfPasswordInBytes + " bytes long but is only " + newPassword.length + " bytes long");} if(newPassword.length > maxLengthOfPasswordInBytes) {throw new IllegalArgumentException("new " + passwordName + " must be at most " + maxLengthOfPasswordInBytes + " bytes long but is " + newPassword.length + " bytes long");} if (securityStatus == null || securityStatus.checkAccessConditions(getLifeCycleState(), new OrSecCondition(changePinCondition,getPinManagementCondition()))) { this.password = newPassword; } else { throw new AccessDeniedException("Access conditions to change " + passwordName + " not met"); } } @Override public void updateLifeCycleState(Iso7816LifeCycleState state) throws AccessDeniedException { if (securityStatus == null || !state.isOperational() || securityStatus.checkAccessConditions(getLifeCycleState(), getPinManagementCondition())) { super.updateLifeCycleState(state); } else { throw new AccessDeniedException("Access conditions to change life cycle state not matched"); } } public SecCondition getPinManagementCondition() { return pinManagementCondition; } }