use of org.openecard.common.util.UtilException in project open-ecard by ecsec.
the class AbstractTerminal method verifyUser.
public VerifyUserResponse verifyUser(VerifyUser verify) throws SCIOException, IFDException {
byte[] handle = verify.getSlotHandle();
// get capabilities
getCapabilities();
// check if is possible to perform PinCompare protocol
List<String> protoList = this.capabilities.getSlotCapability().get(0).getProtocol();
if (!protoList.contains(ECardConstants.Protocol.PIN_COMPARE)) {
throw new IFDException("PinCompare protocol is not supported by this IFD.");
}
// get values from requested command
InputUnitType inputUnit = verify.getInputUnit();
AltVUMessagesType allMsgs = getMessagesOrDefaults(verify.getAltVUMessages());
BigInteger firstTimeout = verify.getTimeoutUntilFirstKey();
firstTimeout = (firstTimeout == null) ? BigInteger.valueOf(60000) : firstTimeout;
BigInteger otherTimeout = verify.getTimeoutAfterFirstKey();
otherTimeout = (otherTimeout == null) ? BigInteger.valueOf(15000) : otherTimeout;
final byte[] template = verify.getTemplate();
VerifyUserResponse response;
Result result;
// check which type of authentication to perform
if (inputUnit.getBiometricInput() != null) {
// TODO: implement
String msg = "Biometric authentication not supported by IFD.";
IFDException ex = new IFDException(ECardConstants.Minor.IFD.IO.UNKNOWN_INPUT_UNIT, msg);
LOG.warn(ex.getMessage(), ex);
throw ex;
} else if (inputUnit.getPinInput() != null) {
final PinInputType pinInput = inputUnit.getPinInput();
// we have a sophisticated card reader
if (terminalInfo.supportsPinCompare()) {
// create custom pinAction to submit pin to terminal
NativePinStepAction pinAction = new NativePinStepAction("enter-pin", pinInput, channel, terminalInfo, template);
// display message instructing user what to do
UserConsentDescription uc = pinUserConsent("action.changepin.userconsent.pinstep.title", pinAction);
UserConsentNavigator ucr = gui.obtainNavigator(uc);
ExecutionEngine exec = new ExecutionEngine(ucr);
// run gui
ResultStatus status = exec.process();
if (status == ResultStatus.CANCEL) {
String msg = "PIN entry cancelled by user.";
LOG.warn(msg);
result = WSHelper.makeResultError(ECardConstants.Minor.IFD.CANCELLATION_BY_USER, msg);
response = WSHelper.makeResponse(VerifyUserResponse.class, result);
} else if (pinAction.exception != null) {
LOG.warn(pinAction.exception.getMessage(), pinAction.exception);
result = WSHelper.makeResultError(ECardConstants.Minor.IFD.AUTHENTICATION_FAILED, pinAction.exception.getMessage());
response = WSHelper.makeResponse(VerifyUserResponse.class, result);
} else {
// input by user
byte[] verifyResponse = pinAction.response;
// evaluate result
result = checkNativePinVerify(verifyResponse);
response = WSHelper.makeResponse(VerifyUserResponse.class, result);
response.setResponse(verifyResponse);
}
return response;
} else if (isVirtual()) {
// software method
// get pin, encode and send
int minLength = pinInput.getPasswordAttributes().getMinLength().intValue();
int maxLength = pinInput.getPasswordAttributes().getMaxLength().intValue();
UserConsentDescription uc = pinUserConsent("action.changepin.userconsent.pinstep.title", minLength, maxLength);
UserConsentNavigator ucr = gui.obtainNavigator(uc);
ExecutionEngine exec = new ExecutionEngine(ucr);
ResultStatus status = exec.process();
if (status == ResultStatus.CANCEL) {
String msg = "PIN entry cancelled by user.";
LOG.warn(msg);
result = WSHelper.makeResultError(ECardConstants.Minor.IFD.CANCELLATION_BY_USER, msg);
response = WSHelper.makeResponse(VerifyUserResponse.class, result);
return response;
}
char[] rawPIN = getPinFromUserConsent(exec);
PasswordAttributesType attributes = pinInput.getPasswordAttributes();
Transmit verifyTransmit;
try {
verifyTransmit = PINUtils.buildVerifyTransmit(rawPIN, attributes, template, handle);
} catch (UtilException e) {
String msg = "Failed to create the verifyTransmit message.";
LOG.error(msg, e);
result = WSHelper.makeResultError(ECardConstants.Minor.IFD.UNKNOWN_ERROR, msg);
response = WSHelper.makeResponse(VerifyUserResponse.class, result);
return response;
} finally {
Arrays.fill(rawPIN, ' ');
}
// send to reader
TransmitResponse transResp;
try {
transResp = ifd.transmit(verifyTransmit);
} finally {
// blank PIN APDU
for (InputAPDUInfoType apdu : verifyTransmit.getInputAPDUInfo()) {
byte[] rawApdu = apdu.getInputAPDU();
if (rawApdu != null) {
Arrays.fill(rawApdu, (byte) 0);
}
}
}
// produce messages
if (transResp.getResult().getResultMajor().equals(ECardConstants.Major.ERROR)) {
if (transResp.getOutputAPDU().isEmpty()) {
result = WSHelper.makeResultError(ECardConstants.Minor.IFD.AUTHENTICATION_FAILED, transResp.getResult().getResultMessage().getValue());
response = WSHelper.makeResponse(VerifyUserResponse.class, result);
return response;
} else {
response = WSHelper.makeResponse(VerifyUserResponse.class, transResp.getResult());
response.setResponse(transResp.getOutputAPDU().get(0));
// TODO: move this code to the PIN Compare protocol
if (response.getResponse() != null) {
CardResponseAPDU resApdu = new CardResponseAPDU(response.getResponse());
byte[] statusBytes = resApdu.getStatusBytes();
boolean isMainStatus = statusBytes[0] == (byte) 0x63;
boolean isMinorStatus = (statusBytes[1] & (byte) 0xF0) == (byte) 0xC0;
int triesLeft = statusBytes[1] & 0x0F;
if (isMainStatus && isMinorStatus && triesLeft > 0) {
LOG.info("PIN not entered successful. There are {} tries left.", statusBytes[1] & 0x0F);
return verifyUser(verify);
}
}
return response;
}
} else {
response = WSHelper.makeResponse(VerifyUserResponse.class, transResp.getResult());
response.setResponse(transResp.getOutputAPDU().get(0));
return response;
}
} else {
IFDException ex = new IFDException("No input unit available to perform PinCompare protocol.");
LOG.warn(ex.getMessage(), ex);
throw ex;
}
} else {
String msg = "Unsupported authentication input method requested.";
IFDException ex = new IFDException(ECardConstants.Minor.IFD.IO.UNKNOWN_INPUT_UNIT, msg);
LOG.warn(ex.getMessage(), ex);
throw ex;
}
}
use of org.openecard.common.util.UtilException in project open-ecard by ecsec.
the class PCSCPinVerify method prepareStructure.
private void prepareStructure(PasswordAttributesType attributes, byte[] cmdTemplate) throws IFDException {
// get apdu and pin template
byte[] pinTemplate;
try {
pinTemplate = PINUtils.createPinMask(attributes);
} catch (UtilException e) {
IFDException ex = new IFDException(e);
throw ex;
}
byte[] template = cmdTemplate;
if (pinTemplate.length > 0) {
template = ByteUtils.concatenate(cmdTemplate, (byte) pinTemplate.length);
template = ByteUtils.concatenate(template, pinTemplate);
}
setData(template);
boolean nibbleHandling = pwdType == PasswordTypeType.BCD || pwdType == PasswordTypeType.ISO_9564_1;
boolean isoPin = pwdType == PasswordTypeType.ISO_9564_1;
// pointer to byte containing pin length in iso encoding
int pinLenIdx = template.length;
int pinPos = isoPin ? pinLenIdx + 1 : pinLenIdx;
// prepare bmFormatString
// bytes
byte bmSysUnits = 1;
byte bmPinPos = (byte) (isoPin ? 1 : 0);
// left
byte bmJustify = 0;
// binary
byte bmPinType = 0;
if (nibbleHandling) {
bmPinType = 1;
} else if (pwdType == PasswordTypeType.ASCII_NUMERIC || pwdType == PasswordTypeType.UTF_8) {
bmPinType = 2;
}
this.bmFormatString = (byte) ((bmSysUnits << 7) | (bmPinPos << 3) | (bmJustify << 2) | bmPinType);
// prepare pin block string
// number of bits of the length field
byte bmPinManagement = (byte) (isoPin ? 4 : 0);
byte pinSize = (byte) (isoPin ? storedLen - 1 : storedLen);
this.bmPINBlockString = (byte) ((bmPinManagement << 4) | pinSize);
// pin length format
// bits
byte bmPinLengthUnit = 0;
byte bmPinBytePos = (byte) (isoPin ? 4 : 0);
bmPINLengthFormat = (byte) ((bmPinLengthUnit << 4) | bmPinBytePos);
setMinPINSize((byte) minLen);
setMaxPINSize((byte) maxLen);
}
use of org.openecard.common.util.UtilException in project open-ecard by ecsec.
the class PINTest method testASCII.
@Test
public void testASCII() throws UtilException {
PasswordAttributesType pwdAttr = create(false, ASCII_NUMERIC, 6, 6);
byte[] pinResult = PINUtils.encodePin("123456".toCharArray(), pwdAttr);
assertEquals(new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 }, pinResult);
try {
pwdAttr = create(true, ASCII_NUMERIC, 6, 6);
PINUtils.encodePin("123456".toCharArray(), pwdAttr);
// padding needed, but no char given
fail();
} catch (UtilException ex) {
}
// try {
// pwdAttr = create(false, ASCII_NUMERIC, 6, 7);
// PINUtils.encodePin("123456", pwdAttr);
// fail(); // padding inferred, but no char given
// } catch (UtilException ex) {
// }
}
use of org.openecard.common.util.UtilException in project open-ecard by ecsec.
the class PCSCPinModify method prepareStructure.
private void prepareStructure(PasswordAttributesType attributes, byte[] cmdTemplate) throws IFDException {
// get apdu and pin template
byte[] pinTemplate;
try {
pinTemplate = PINUtils.createPinMask(attributes);
} catch (UtilException e) {
IFDException ex = new IFDException(e);
throw ex;
}
byte[] template = cmdTemplate;
if (pinTemplate.length > 0) {
template = ByteUtils.concatenate(cmdTemplate, (byte) pinTemplate.length);
template = ByteUtils.concatenate(template, pinTemplate);
}
setData(template);
boolean nibbleHandling = pwdType == PasswordTypeType.BCD || pwdType == PasswordTypeType.ISO_9564_1;
boolean isoPin = pwdType == PasswordTypeType.ISO_9564_1;
// pointer to byte containing pin length in iso encoding
int pinLenIdx = template.length;
int pinPos = isoPin ? pinLenIdx + 1 : pinLenIdx;
// prepare bmFormatString
// bytes
byte bmSysUnits = 1;
byte bmPinPos = (byte) (isoPin ? 1 : 0);
// left
byte bmJustify = 0;
// binary
byte bmPinType = 0;
if (nibbleHandling) {
bmPinType = 1;
} else if (pwdType == PasswordTypeType.ASCII_NUMERIC) {
bmPinType = 2;
}
this.bmFormatString = (byte) ((bmSysUnits << 7) | (bmPinPos << 3) | (bmJustify << 2) | bmPinType);
// prepare pin block string
// number of bits of the length field
byte bmPinManagement = (byte) (isoPin ? 4 : 0);
byte pinSize = (byte) (isoPin ? storedLen - 1 : storedLen);
this.bmPINBlockString = (byte) ((bmPinManagement << 4) | pinSize);
// pin length format
// bits
byte bmPinLengthUnit = 0;
byte bmPinBytePos = (byte) (isoPin ? 4 : 0);
bmPINLengthFormat = (byte) ((bmPinLengthUnit << 4) | bmPinBytePos);
setMinPINSize((byte) minLen);
setMaxPINSize((byte) maxLen);
}
Aggregations