use of iso.std.iso_iec._24727.tech.schema.VerifyUser 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 iso.std.iso_iec._24727.tech.schema.VerifyUser in project open-ecard by ecsec.
the class IFD method verifyUser.
@Override
public VerifyUserResponse verifyUser(VerifyUser parameters) {
// TODO: convert to IFD Protocol
try {
VerifyUserResponse response;
if (!hasContext()) {
String msg = "Context not initialized.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
response = WSHelper.makeResponse(VerifyUserResponse.class, r);
return response;
}
SingleThreadChannel channel = cm.getSlaveChannel(parameters.getSlotHandle());
AbstractTerminal aTerm = new AbstractTerminal(this, cm, channel, gui, ctxHandle, parameters.getDisplayIndex());
try {
response = aTerm.verifyUser(parameters);
return response;
} catch (IFDException ex) {
response = WSHelper.makeResponse(VerifyUserResponse.class, ex.getResult());
return response;
}
} catch (Exception ex) {
LOG.warn(ex.getMessage(), ex);
throwThreadKillException(ex);
return WSHelper.makeResponse(VerifyUserResponse.class, WSHelper.makeResult(ex));
}
}
use of iso.std.iso_iec._24727.tech.schema.VerifyUser in project open-ecard by ecsec.
the class DIDAuthenticateStep method perform.
@Override
public DIDAuthenticateResponse perform(DIDAuthenticate request, Map<String, Object> internalData) {
DIDAuthenticateResponse response = WSHelper.makeResponse(DIDAuthenticateResponse.class, WSHelper.makeResultOK());
char[] rawPIN = null;
try {
ConnectionHandleType connectionHandle = SALUtils.getConnectionHandle(request);
String didName = SALUtils.getDIDName(request);
CardStateEntry cardStateEntry = SALUtils.getCardStateEntry(internalData, connectionHandle);
PINCompareDIDAuthenticateInputType pinCompareInput = new PINCompareDIDAuthenticateInputType(request.getAuthenticationProtocolData());
PINCompareDIDAuthenticateOutputType pinCompareOutput = pinCompareInput.getOutputType();
byte[] cardApplication;
if (request.getDIDScope() != null && request.getDIDScope().equals(DIDScopeType.GLOBAL)) {
cardApplication = cardStateEntry.getInfo().getApplicationIdByDidName(request.getDIDName(), request.getDIDScope());
} else {
cardApplication = connectionHandle.getCardApplication();
}
Assert.securityConditionDID(cardStateEntry, cardApplication, didName, DifferentialIdentityServiceActionName.DID_AUTHENTICATE);
DIDStructureType didStructure = cardStateEntry.getDIDStructure(didName, cardApplication);
PINCompareMarkerType pinCompareMarker = new PINCompareMarkerType(didStructure.getDIDMarker());
byte keyRef = pinCompareMarker.getPINRef().getKeyRef()[0];
byte[] slotHandle = connectionHandle.getSlotHandle();
PasswordAttributesType attributes = pinCompareMarker.getPasswordAttributes();
rawPIN = pinCompareInput.getPIN();
// delete pin from memory of the structure
pinCompareInput.setPIN(null);
byte[] template = new byte[] { 0x00, 0x20, 0x00, keyRef };
byte[] responseCode;
// with [ISO7816-4] (Section 7.5.6).
if (rawPIN == null || rawPIN.length == 0) {
VerifyUser verify = new VerifyUser();
verify.setSlotHandle(slotHandle);
InputUnitType inputUnit = new InputUnitType();
verify.setInputUnit(inputUnit);
PinInputType pinInput = new PinInputType();
inputUnit.setPinInput(pinInput);
pinInput.setIndex(BigInteger.ZERO);
pinInput.setPasswordAttributes(attributes);
verify.setTemplate(template);
VerifyUserResponse verifyR = (VerifyUserResponse) dispatcher.safeDeliver(verify);
WSHelper.checkResult(verifyR);
responseCode = verifyR.getResponse();
} else {
Transmit verifyTransmit = PINUtils.buildVerifyTransmit(rawPIN, attributes, template, slotHandle);
try {
TransmitResponse transResp = (TransmitResponse) dispatcher.safeDeliver(verifyTransmit);
WSHelper.checkResult(transResp);
responseCode = transResp.getOutputAPDU().get(0);
} finally {
// blank PIN APDU
for (InputAPDUInfoType apdu : verifyTransmit.getInputAPDUInfo()) {
byte[] rawApdu = apdu.getInputAPDU();
if (rawApdu != null) {
java.util.Arrays.fill(rawApdu, (byte) 0);
}
}
}
}
CardResponseAPDU verifyResponseAPDU = new CardResponseAPDU(responseCode);
if (verifyResponseAPDU.isWarningProcessed()) {
pinCompareOutput.setRetryCounter(new BigInteger(Integer.toString((verifyResponseAPDU.getSW2() & 0x0F))));
}
cardStateEntry.addAuthenticated(didName, cardApplication);
response.setAuthenticationProtocolData(pinCompareOutput.getAuthDataType());
} catch (ECardException e) {
LOG.error(e.getMessage(), e);
response.setResult(e.getResult());
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
LOG.error(e.getMessage(), e);
response.setResult(WSHelper.makeResult(e));
} finally {
if (rawPIN != null) {
Arrays.fill(rawPIN, ' ');
}
}
return response;
}
use of iso.std.iso_iec._24727.tech.schema.VerifyUser in project open-ecard by ecsec.
the class PINTest method verifyeGK.
@Test(enabled = false)
public void verifyeGK() {
IFD ifd = new IFD();
ifd.setGUI(new SwingUserConsent(new SwingDialogWrapper()));
EstablishContext eCtx = new EstablishContext();
byte[] ctxHandle = ifd.establishContext(eCtx).getContextHandle();
ListIFDs listIFDs = new ListIFDs();
listIFDs.setContextHandle(ctxHandle);
String ifdName = ifd.listIFDs(listIFDs).getIFDName().get(0);
Connect connect = new Connect();
connect.setContextHandle(ctxHandle);
connect.setIFDName(ifdName);
connect.setSlot(BigInteger.ZERO);
byte[] slotHandle = ifd.connect(connect).getSlotHandle();
VerifyUser verify = new VerifyUser();
verify.setSlotHandle(slotHandle);
InputUnitType inputUnit = new InputUnitType();
verify.setInputUnit(inputUnit);
PinInputType pinInput = new PinInputType();
inputUnit.setPinInput(pinInput);
pinInput.setIndex(BigInteger.ZERO);
pinInput.setPasswordAttributes(create(true, ISO_9564_1, 6, 8, 8));
verify.setTemplate(StringUtils.toByteArray("00 20 00 01", true));
VerifyUserResponse verifyR = ifd.verifyUser(verify);
byte[] responseCode = verifyR.getResponse();
}
Aggregations