use of org.openecard.ifd.scio.reader.ExecutePACEResponse in project open-ecard by ecsec.
the class IFD method destroyChannel.
@Override
public DestroyChannelResponse destroyChannel(DestroyChannel parameters) {
try {
DestroyChannelResponse destroyChannelResponse = new DestroyChannelResponse();
byte[] slotHandle = parameters.getSlotHandle();
SingleThreadChannel channel = cm.getSlaveChannel(slotHandle);
TerminalInfo termInfo = new TerminalInfo(cm, channel);
// check if it is PACE and try to perform native implementation
// get pace capabilities
List<PACECapabilities.PACECapability> paceCapabilities = termInfo.getPACECapabilities();
if (paceCapabilities.contains(PACECapabilities.PACECapability.DestroyPACEChannel)) {
ExecutePACERequest execPaceReq = new ExecutePACERequest(ExecutePACERequest.Function.DestroyPACEChannel);
byte[] reqData = execPaceReq.toBytes();
LOG.debug("executeCtrlCode request: {}", ByteUtils.toHexString(reqData));
// execute pace
Map<Integer, Integer> features = termInfo.getFeatureCodes();
byte[] resData = channel.transmitControlCommand(features.get(PCSCFeatures.EXECUTE_PACE), reqData);
LOG.debug("Response of executeCtrlCode: {}", ByteUtils.toHexString(resData));
// evaluate response
ExecutePACEResponse execPaceRes = new ExecutePACEResponse(resData);
if (execPaceRes.isError()) {
destroyChannelResponse = WSHelper.makeResponse(DestroyChannelResponse.class, execPaceRes.getResult());
}
}
channel.removeSecureMessaging();
if (destroyChannelResponse.getResult() == null) {
Result r = new Result();
r.setResultMajor(ECardConstants.Major.OK);
destroyChannelResponse.setResult(r);
}
return destroyChannelResponse;
} catch (Throwable t) {
return WSHelper.makeResponse(DestroyChannelResponse.class, WSHelper.makeResult(t));
}
}
use of org.openecard.ifd.scio.reader.ExecutePACEResponse in project open-ecard by ecsec.
the class TerminalInfo method getPACECapabilities.
public List<PACECapabilities.PACECapability> getPACECapabilities() throws SCIOException {
List<PACECapabilities.PACECapability> result = new LinkedList<>();
if (PACECapabilities == null) {
if (isConnected()) {
if (supportsPace()) {
int ctrlCode = getPaceCtrlCode();
ExecutePACERequest.Function paceFunc = ExecutePACERequest.Function.GetReaderPACECapabilities;
byte[] getCapabilityRequest = new ExecutePACERequest(paceFunc).toBytes();
byte[] response = channel.transmitControlCommand(ctrlCode, getCapabilityRequest);
ExecutePACEResponse paceResponse = new ExecutePACEResponse(response);
if (paceResponse.isError()) {
String msg = "PACE is advertised but the result iss errornous.\n";
msg += paceResponse.getResult().getResultMessage().getValue();
throw new SCIOException(msg, SCIOErrorCode.SCARD_F_UNKNOWN_ERROR);
}
PACECapabilities cap = new PACECapabilities(paceResponse.getData());
PACECapabilities = cap.getFeaturesEnum();
result.addAll(PACECapabilities);
}
}
} else {
result.addAll(PACECapabilities);
}
return Collections.unmodifiableList(result);
}
use of org.openecard.ifd.scio.reader.ExecutePACEResponse in project open-ecard by ecsec.
the class IFD method establishChannel.
@Override
public EstablishChannelResponse establishChannel(EstablishChannel parameters) {
byte[] slotHandle = parameters.getSlotHandle();
try {
SingleThreadChannel channel = cm.getSlaveChannel(slotHandle);
TerminalInfo termInfo = new TerminalInfo(cm, channel);
DIDAuthenticationDataType protoParam = parameters.getAuthenticationProtocolData();
String protocol = protoParam.getProtocol();
// check if it is PACE and try to perform native implementation
// get pace capabilities
List<PACECapabilities.PACECapability> paceCapabilities = termInfo.getPACECapabilities();
List<String> supportedProtos = TerminalInfo.buildPACEProtocolList(paceCapabilities);
// i don't care which type is supported, i try it anyways
if (!supportedProtos.isEmpty() && supportedProtos.get(0).startsWith(protocol)) {
// yeah, PACE seems to be supported by the reader, big win
PACEInputType paceParam = new PACEInputType(protoParam);
// extract variables needed for pace
byte pinID = paceParam.getPINID();
// optional elements
byte[] chat = paceParam.getCHAT();
String pin = paceParam.getPIN();
byte[] certDesc = paceParam.getCertificateDescription();
// prepare pace data structures
// TODO: add supplied PIN
EstablishPACERequest estPaceReq = new EstablishPACERequest(pinID, chat, null, certDesc);
ExecutePACERequest execPaceReq = new ExecutePACERequest(ExecutePACERequest.Function.EstablishPACEChannel, estPaceReq.toBytes());
// TODO: check if this additional check is really necessary
if (estPaceReq.isSupportedType(paceCapabilities)) {
byte[] reqData = execPaceReq.toBytes();
LOG.debug("executeCtrlCode request: {}", ByteUtils.toHexString(reqData));
// execute pace
Map<Integer, Integer> features = termInfo.getFeatureCodes();
byte[] resData = channel.transmitControlCommand(features.get(PCSCFeatures.EXECUTE_PACE), reqData);
LOG.debug("Response of executeCtrlCode: {}", ByteUtils.toHexString(resData));
// evaluate response
ExecutePACEResponse execPaceRes = new ExecutePACEResponse(resData);
if (execPaceRes.isError()) {
return WSHelper.makeResponse(EstablishChannelResponse.class, execPaceRes.getResult());
}
EstablishPACEResponse estPaceRes = new EstablishPACEResponse(execPaceRes.getData());
// get values and prepare response
PACEOutputType authDataResponse = paceParam.getOutputType();
// mandatory fields
authDataResponse.setRetryCounter(estPaceRes.getRetryCounter());
authDataResponse.setEFCardAccess(estPaceRes.getEFCardAccess());
// optional fields
if (estPaceRes.hasCurrentCAR()) {
authDataResponse.setCurrentCAR(estPaceRes.getCurrentCAR());
}
if (estPaceRes.hasPreviousCAR()) {
authDataResponse.setPreviousCAR(estPaceRes.getPreviousCAR());
}
if (estPaceRes.hasIDICC()) {
authDataResponse.setIDPICC(estPaceRes.getIDICC());
}
// create response type and return
EstablishChannelResponse response = WSHelper.makeResponse(EstablishChannelResponse.class, WSHelper.makeResultOK());
response.setAuthenticationProtocolData(authDataResponse.getAuthDataType());
return response;
}
}
// check out available software protocols
if (this.protocolFactories.contains(protocol)) {
ProtocolFactory factory = this.protocolFactories.get(protocol);
Protocol protoImpl = factory.createInstance();
EstablishChannelResponse response = protoImpl.establish(parameters, env.getDispatcher(), this.gui);
// register protocol instance for secure messaging when protocol was processed successful
if (response.getResult().getResultMajor().equals(ECardConstants.Major.OK)) {
channel.addSecureMessaging(protoImpl);
}
return response;
}
// if this point is reached a native implementation is not present, try registered protocols
Result r = WSHelper.makeResultUnknownError("No such protocol available in this IFD.");
return WSHelper.makeResponse(EstablishChannelResponse.class, r);
} catch (Throwable t) {
return WSHelper.makeResponse(EstablishChannelResponse.class, WSHelper.makeResult(t));
}
}
Aggregations