Search in sources :

Example 16 with DynamicContext

use of org.openecard.common.DynamicContext in project open-ecard by ecsec.

the class EacNavigator method next.

@Override
public StepResult next() {
    // if cancel call has been issued, abort the whole process
    if (this.guiService.isCancelled()) {
        // prevent index out of bounds
        int i = idx == -1 ? 0 : idx > steps.size() ? steps.size() - 1 : idx;
        return new AndroidResult(steps.get(i), ResultStatus.CANCEL, Collections.EMPTY_LIST);
    }
    // handle step display
    if (idx == -1) {
        idx++;
        return new AndroidResult(steps.get(idx), ResultStatus.OK, Collections.EMPTY_LIST);
    } else if (idx == 0) {
        idx++;
        Step cvcStep = steps.get(0);
        Step chatStep = steps.get(1);
        try {
            this.guiService.loadValuesFromSteps(cvcStep, chatStep);
            List<OutputInfoUnit> outInfo = this.guiService.getSelection();
            return new AndroidResult(chatStep, ResultStatus.OK, outInfo);
        } catch (InterruptedException ex) {
            return new AndroidResult(chatStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
        }
    } else if (idx == 1) {
        idx++;
        Step pinStep = steps.get(2);
        if (pinFirstUse) {
            pinFirstUse = false;
        } else {
            this.guiService.setPinCorrect(false);
        }
        // get blocked status from dynamic context
        DynamicContext ctx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
        EacPinStatus blockedStatus = (EacPinStatus) ctx.get(EACProtocol.PIN_STATUS);
        if (blockedStatus == EacPinStatus.BLOCKED || blockedStatus == EacPinStatus.DEACTIVATED) {
            this.guiService.sendPinStatus(blockedStatus);
            return new AndroidResult(pinStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
        }
        // ask user for the pin
        try {
            List<OutputInfoUnit> outInfo = this.guiService.getPinResult(pinStep);
            writeBackValues(pinStep.getInputInfoUnits(), outInfo);
            return new AndroidResult(pinStep, ResultStatus.OK, outInfo);
        } catch (InterruptedException ex) {
            return new AndroidResult(pinStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
        }
    } else if (idx == 2) {
        idx++;
        Step s = steps.get(idx);
        // get blocked status from dynamic context
        DynamicContext ctx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
        EacPinStatus blockedStatus = (EacPinStatus) ctx.get(EACProtocol.PIN_STATUS);
        if (blockedStatus == EacPinStatus.BLOCKED || blockedStatus == EacPinStatus.DEACTIVATED) {
            this.guiService.setPinCorrect(false);
            this.guiService.sendPinStatus(blockedStatus);
            return new AndroidResult(s, ResultStatus.CANCEL, Collections.EMPTY_LIST);
        }
        if ("PROTOCOL_GUI_STEP_PROCESSING".equals(s.getID())) {
            this.guiService.setPinCorrect(true);
            return new AndroidResult(s, ResultStatus.OK, Collections.EMPTY_LIST);
        } else {
            this.guiService.setPinCorrect(false);
            return new AndroidResult(s, ResultStatus.CANCEL, Collections.EMPTY_LIST);
        }
    } else {
        Step s = steps.get(idx);
        idx++;
        return new AndroidResult(s, ResultStatus.OK, Collections.EMPTY_LIST);
    }
}
Also used : AndroidResult(org.openecard.gui.android.AndroidResult) ArrayList(java.util.ArrayList) List(java.util.List) OutputInfoUnit(org.openecard.gui.definition.OutputInfoUnit) Step(org.openecard.gui.definition.Step) EacPinStatus(org.openecard.sal.protocol.eac.gui.EacPinStatus) DynamicContext(org.openecard.common.DynamicContext)

Example 17 with DynamicContext

use of org.openecard.common.DynamicContext in project open-ecard by ecsec.

the class TCTokenHandler method handleActivate.

/**
 * Activates the client according to the received TCToken.
 *
 * @param request The activation request containing the TCToken.
 * @return The response containing the result of the activation process.
 * @throws InvalidRedirectUrlException Thrown in case no redirect URL could be determined.
 * @throws SecurityViolationException
 * @throws NonGuiException
 */
public TCTokenResponse handleActivate(TCTokenRequest request) throws InvalidRedirectUrlException, SecurityViolationException, NonGuiException {
    TCToken token = request.getTCToken();
    if (LOG.isDebugEnabled()) {
        try {
            WSMarshaller m = WSMarshallerFactory.createInstance();
            LOG.debug("TCToken:\n{}", m.doc2str(m.marshal(token)));
        } catch (TransformerException | WSMarshallerException ex) {
        // it's no use
        }
    }
    final DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
    boolean performChecks = isPerformTR03112Checks(request);
    if (!performChecks) {
        LOG.warn("Checks according to BSI TR03112 3.4.2, 3.4.4 (TCToken specific) and 3.4.5 are disabled.");
    }
    boolean isObjectActivation = request.getTCTokenURL() == null;
    if (isObjectActivation) {
        LOG.warn("Checks according to BSI TR03112 3.4.4 (TCToken specific) are disabled.");
    }
    dynCtx.put(TR03112Keys.TCTOKEN_CHECKS, performChecks);
    dynCtx.put(TR03112Keys.OBJECT_ACTIVATION, isObjectActivation);
    dynCtx.put(TR03112Keys.TCTOKEN_SERVER_CERTIFICATES, request.getCertificates());
    ConnectionHandleType connectionHandle = null;
    TCTokenResponse response = new TCTokenResponse();
    response.setTCToken(token);
    byte[] requestedContextHandle = request.getContextHandle();
    String ifdName = request.getIFDName();
    BigInteger requestedSlotIndex = request.getSlotIndex();
    // we know exactly which card we want
    ConnectionHandleType requestedHandle = new ConnectionHandleType();
    requestedHandle.setContextHandle(requestedContextHandle);
    requestedHandle.setIFDName(ifdName);
    requestedHandle.setSlotIndex(requestedSlotIndex);
    Set<CardStateEntry> matchingHandles = cardStates.getMatchingEntries(requestedHandle);
    if (!matchingHandles.isEmpty()) {
        connectionHandle = matchingHandles.toArray(new CardStateEntry[] {})[0].handleCopy();
    }
    if (connectionHandle == null) {
        String msg = LANG_TOKEN.translationForKey("cancel");
        LOG.error(msg);
        response.setResult(WSHelper.makeResultError(ResultMinor.CANCELLATION_BY_USER, msg));
        // fill in values, so it is usuable by the transport module
        response = determineRefreshURL(request, response);
        response.finishResponse(true);
        return response;
    }
    try {
        // process binding and follow redirect addresses afterwards
        response = processBinding(request, connectionHandle);
        // fill in values, so it is usuable by the transport module
        response = determineRefreshURL(request, response);
        response.finishResponse(isObjectActivation);
        return response;
    } catch (DispatcherException w) {
        LOG.error(w.getMessage(), w);
        response.setResultCode(BindingResultCode.INTERNAL_ERROR);
        response.setResult(WSHelper.makeResultError(ResultMinor.CLIENT_ERROR, w.getMessage()));
        showErrorMessage(w.getMessage());
        throw new NonGuiException(response, w.getMessage(), w);
    } catch (PAOSException w) {
        LOG.error(w.getMessage(), w);
        // find actual error to display to the user
        Throwable innerException = w.getCause();
        if (innerException == null) {
            innerException = w;
        } else if (innerException instanceof ExecutionException) {
            innerException = innerException.getCause();
        }
        String errorMsg = innerException.getLocalizedMessage();
        // fix NPE when null is returned instead of a message
        errorMsg = errorMsg == null ? "" : errorMsg;
        switch(errorMsg) {
            case "The target server failed to respond":
                errorMsg = LANG_TR.translationForKey(NO_RESPONSE_FROM_SERVER);
                break;
            case ECardConstants.Minor.App.INT_ERROR + " ==> Unknown eCard exception occurred.":
                errorMsg = LANG_TR.translationForKey(UNKNOWN_ECARD_ERROR);
                break;
            case "Internal TLS error, this could be an attack":
                errorMsg = LANG_TR.translationForKey(INTERNAL_TLS_ERROR);
                break;
        }
        if (innerException instanceof WSException) {
            WSException ex = (WSException) innerException;
            errorMsg = createResponseFromWsEx(ex, response);
        } else if (innerException instanceof PAOSConnectionException) {
            response.setResult(WSHelper.makeResultError(ResultMinor.TRUSTED_CHANNEL_ESTABLISCHMENT_FAILED, w.getLocalizedMessage()));
        } else {
            errorMsg = createMessageFromUnknownError(w);
            response.setResult(WSHelper.makeResultError(ResultMinor.CLIENT_ERROR, w.getMessage()));
        }
        showErrorMessage(errorMsg);
        try {
            // fill in values, so it is usuable by the transport module
            response = determineRefreshURL(request, response);
            response.finishResponse(true);
        } catch (InvalidRedirectUrlException ex) {
            LOG.error(ex.getMessage(), ex);
            response.setResultCode(BindingResultCode.INTERNAL_ERROR);
            response.setResult(WSHelper.makeResultError(ResultMinor.CLIENT_ERROR, ex.getLocalizedMessage()));
            throw new NonGuiException(response, ex.getMessage(), ex);
        } catch (SecurityViolationException ex) {
            String msg2 = "The RefreshAddress contained in the TCToken is invalid. Redirecting to the " + "CommunicationErrorAddress.";
            LOG.error(msg2, ex);
            response.setResultCode(BindingResultCode.REDIRECT);
            response.setResult(WSHelper.makeResultError(ResultMinor.COMMUNICATION_ERROR, msg2));
            response.addAuxResultData(AuxDataKeys.REDIRECT_LOCATION, ex.getBindingResult().getAuxResultData().get(AuxDataKeys.REDIRECT_LOCATION));
        }
        return response;
    }
}
Also used : ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) InvalidRedirectUrlException(org.openecard.binding.tctoken.ex.InvalidRedirectUrlException) CardStateEntry(org.openecard.common.sal.state.CardStateEntry) WSMarshallerException(org.openecard.ws.marshal.WSMarshallerException) SecurityViolationException(org.openecard.binding.tctoken.ex.SecurityViolationException) WSMarshaller(org.openecard.ws.marshal.WSMarshaller) DispatcherException(org.openecard.common.interfaces.DispatcherException) PAOSException(org.openecard.transport.paos.PAOSException) PAOSConnectionException(org.openecard.transport.paos.PAOSConnectionException) BigInteger(java.math.BigInteger) WSException(org.openecard.common.WSHelper.WSException) NonGuiException(org.openecard.binding.tctoken.ex.NonGuiException) ExecutionException(java.util.concurrent.ExecutionException) TransformerException(javax.xml.transform.TransformerException) DynamicContext(org.openecard.common.DynamicContext)

Example 18 with DynamicContext

use of org.openecard.common.DynamicContext in project open-ecard by ecsec.

the class TCTokenRequest method parseTCTokenRequestURI.

private static TCTokenRequest parseTCTokenRequestURI(Map<String, String> queries, Context ctx) throws InvalidTCTokenException, MissingActivationParameterException, AuthServerException, InvalidRedirectUrlException, InvalidTCTokenElement, InvalidTCTokenUrlException, SecurityViolationException, InvalidAddressException, UserCancellationException {
    TCTokenRequest tcTokenRequest = new TCTokenRequest();
    try {
        if (queries.containsKey("cardTypes") || queries.containsKey("cardType")) {
            String[] types;
            if (queries.containsKey("cardType")) {
                types = new String[] { queries.get("cardType") };
            } else {
                types = queries.get("cardTypes").split(",");
            }
            ConnectionHandleType handle = findCard(types, ctx);
            setIfdName(queries, handle.getIFDName());
            setContextHandle(queries, handle.getContextHandle());
            setSlotIndex(queries, handle.getSlotIndex());
            addTokenUrlParameter(queries, handle.getRecognitionInfo());
        } else {
            String[] types = new String[] { tcTokenRequest.cardType };
            ConnectionHandleType handle = findCard(types, ctx);
            setIfdName(queries, handle.getIFDName());
            setContextHandle(queries, handle.getContextHandle());
            setSlotIndex(queries, handle.getSlotIndex());
        }
    } catch (UserCancellationException ex) {
        if (queries.containsKey("cardTypes")) {
            addTokenUrlParameter(queries, queries.get("cardTypes").split(",")[0]);
        }
        LOG.warn("The user aborted the CardInsertion dialog.", ex);
        DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
        dynCtx.put(TR03112Keys.CARD_SELECTION_CANCELLATION, ex);
    }
    String activationTokenUrl = null;
    for (Map.Entry<String, String> next : queries.entrySet()) {
        String k = next.getKey();
        k = k == null ? "" : k;
        String v = next.getValue();
        if (v == null || v.isEmpty()) {
            LOG.info("Skipping query parameter '{}' because it does not contain a value.", k);
        } else {
            switch(k) {
                case "tcTokenURL":
                    activationTokenUrl = v;
                    break;
                case "ifdName":
                    tcTokenRequest.ifdName = v;
                    break;
                case "contextHandle":
                    tcTokenRequest.contextHandle = StringUtils.toByteArray(v);
                    break;
                case "slotIndex":
                    tcTokenRequest.slotIndex = new BigInteger(v);
                    break;
                case "cardType":
                    tcTokenRequest.cardType = v;
                    break;
                default:
                    LOG.info("Unknown query element: {}", k);
                    break;
            }
        }
    }
    // cardType determined! set in dynamic context, so the information is available in ResourceContext
    DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
    dynCtx.put(TR03112Keys.ACTIVATION_CARD_TYPE, tcTokenRequest.cardType);
    if (activationTokenUrl != null) {
        try {
            URL tokenUrl = new URL(activationTokenUrl);
            TCTokenContext tokenCtx = TCTokenContext.generateTCToken(tokenUrl);
            tcTokenRequest.tokenCtx = tokenCtx;
            tcTokenRequest.token = tokenCtx.getToken();
            tcTokenRequest.certificates = tokenCtx.getCerts();
            tcTokenRequest.tcTokenURL = tokenUrl;
        } catch (MalformedURLException ex) {
            // TODO: check if the error type is correct, was WRONG_PARAMETER before
            throw new InvalidTCTokenUrlException(INVALID_TCTOKEN_URL, ex, activationTokenUrl);
        }
    }
    if (tcTokenRequest.token == null) {
        throw new MissingActivationParameterException(NO_TOKEN);
    }
    return tcTokenRequest;
}
Also used : ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) MalformedURLException(java.net.MalformedURLException) MissingActivationParameterException(org.openecard.binding.tctoken.ex.MissingActivationParameterException) URL(java.net.URL) InvalidTCTokenUrlException(org.openecard.binding.tctoken.ex.InvalidTCTokenUrlException) UserCancellationException(org.openecard.binding.tctoken.ex.UserCancellationException) BigInteger(java.math.BigInteger) HashMap(java.util.HashMap) Map(java.util.Map) DynamicContext(org.openecard.common.DynamicContext)

Example 19 with DynamicContext

use of org.openecard.common.DynamicContext in project open-ecard by ecsec.

the class TCTokenVerifier method checkUserCancellation.

private void checkUserCancellation() throws InvalidRedirectUrlException, InvalidTCTokenElement, UserCancellationException {
    DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
    UserCancellationException ex = (UserCancellationException) dynCtx.get(TR03112Keys.CARD_SELECTION_CANCELLATION);
    if (ex != null) {
        determineRefreshAddress(ex);
    }
}
Also used : UserCancellationException(org.openecard.binding.tctoken.ex.UserCancellationException) DynamicContext(org.openecard.common.DynamicContext)

Example 20 with DynamicContext

use of org.openecard.common.DynamicContext in project open-ecard by ecsec.

the class RedirectCertificateValidator method validate.

@Override
public VerifierResult validate(URL url, TlsServerCertificate cert) throws ValidationError {
    try {
        // disable certificate checks according to BSI TR03112-7 in some situations
        if (redirectChecks) {
            CertificateDescription desc = (CertificateDescription) descPromise.derefNonblocking();
            certDescExists = desc != null;
            String host = url.getProtocol() + "://" + url.getHost() + (url.getPort() == -1 ? "" : (":" + url.getPort()));
            // check points certificate (but just in case we have a certificate description)
            if (certDescExists && !TR03112Utils.isInCommCertificates(cert, desc.getCommCertificates(), host)) {
                LOG.error("The retrieved server certificate is NOT contained in the CommCertificates of " + "the CertificateDescription extension of the eService certificate.");
                throw new ValidationError(INVALID_REDIRECT);
            }
            // check if we match the SOP
            URL sopUrl;
            if (certDescExists && desc.getSubjectURL() != null && !desc.getSubjectURL().isEmpty()) {
                sopUrl = new URL(desc.getSubjectURL());
            } else {
                DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
                sopUrl = (URL) dynCtx.get(TR03112Keys.TCTOKEN_URL);
            }
            // on th efirst invocation this is the current URL, on the following invocations this is the last used
            if (lastURL == null) {
                lastURL = url;
            }
            // check SOP for last URL and update the URL
            boolean SOP = TR03112Utils.checkSameOriginPolicy(lastURL, sopUrl);
            lastURL = url;
            if (!SOP) {
                // there is more to come
                return VerifierResult.CONTINUE;
            } else {
                // SOP fulfilled
                return VerifierResult.FINISH;
            }
        } else {
            // in that case its equally valid to let the browser do the redirects
            return VerifierResult.FINISH;
        }
    } catch (MalformedURLException ex) {
        throw new ValidationError(REDIRECT_MALFORMED_URL, ex);
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) CertificateDescription(org.openecard.crypto.common.asn1.cvc.CertificateDescription) URL(java.net.URL) DynamicContext(org.openecard.common.DynamicContext)

Aggregations

DynamicContext (org.openecard.common.DynamicContext)22 URL (java.net.URL)5 MalformedURLException (java.net.MalformedURLException)4 ObjectSchemaValidator (org.openecard.common.interfaces.ObjectSchemaValidator)4 ObjectValidatorException (org.openecard.common.interfaces.ObjectValidatorException)4 Promise (org.openecard.common.util.Promise)4 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)3 DIDAuthenticateResponse (iso.std.iso_iec._24727.tech.schema.DIDAuthenticateResponse)3 Pair (org.openecard.common.util.Pair)3 StepActionResult (org.openecard.gui.executor.StepActionResult)3 DIDAuthenticate (iso.std.iso_iec._24727.tech.schema.DIDAuthenticate)2 IOException (java.io.IOException)2 BigInteger (java.math.BigInteger)2 URISyntaxException (java.net.URISyntaxException)2 InvalidAddressException (org.openecard.binding.tctoken.ex.InvalidAddressException)2 UserCancellationException (org.openecard.binding.tctoken.ex.UserCancellationException)2 TlsServerCertificate (org.openecard.bouncycastle.tls.TlsServerCertificate)2 CardVerifiableCertificate (org.openecard.crypto.common.asn1.cvc.CardVerifiableCertificate)2 CardVerifiableCertificateChain (org.openecard.crypto.common.asn1.cvc.CardVerifiableCertificateChain)2 UserConsentNavigator (org.openecard.gui.UserConsentNavigator)2