Search in sources :

Example 1 with ClientCertDefaultTlsClient

use of org.openecard.crypto.tls.ClientCertDefaultTlsClient in project open-ecard by ecsec.

the class ResourceContext method getStreamInt.

private static ResourceContext getStreamInt(URL url, CertificateValidator v, List<Pair<URL, TlsServerCertificate>> serverCerts, int maxRedirects) throws IOException, ResourceException, ValidationError, InvalidAddressException {
    try {
        DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
        CookieManager cManager = (CookieManager) dynCtx.get(TR03112Keys.COOKIE_MANAGER);
        LOG.info("Trying to load resource from: {}", url);
        if (maxRedirects == 0) {
            throw new ResourceException(MAX_REDIRECTS);
        }
        maxRedirects--;
        String protocol = url.getProtocol();
        String hostname = url.getHost();
        int port = url.getPort();
        if (port == -1) {
            port = url.getDefaultPort();
        }
        String resource = url.getFile();
        resource = resource.isEmpty() ? "/" : resource;
        if (!"https".equals(protocol)) {
            throw new InvalidAddressException(INVALID_ADDRESS);
        }
        // open a TLS connection, retrieve the server certificate and save it
        TlsClientProtocol h;
        DynamicAuthentication tlsAuth = new DynamicAuthentication(hostname);
        // add PKIX validator if not doin nPA auth
        if (isPKIXVerify()) {
            tlsAuth.addCertificateVerifier(new JavaSecVerifier());
        }
        // FIXME: validate certificate chain as soon as a usable solution exists for the trust problem
        // tlsAuth.setCertificateVerifier(new JavaSecVerifier());
        TlsCrypto crypto = new BcTlsCrypto(ReusableSecureRandom.getInstance());
        ClientCertTlsClient tlsClient = new ClientCertDefaultTlsClient(crypto, hostname, true);
        tlsClient.setAuthentication(tlsAuth);
        // connect tls client
        tlsClient.setClientVersion(ProtocolVersion.TLSv12);
        Socket socket = ProxySettings.getDefault().getSocket(protocol, hostname, port);
        h = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream());
        LOG.debug("Performing TLS handshake.");
        h.connect(tlsClient);
        LOG.debug("TLS handshake performed.");
        serverCerts.add(new Pair<>(url, tlsAuth.getServerCertificate()));
        // check result
        CertificateValidator.VerifierResult verifyResult = v.validate(url, tlsAuth.getServerCertificate());
        if (verifyResult == CertificateValidator.VerifierResult.FINISH) {
            List<Pair<URL, TlsServerCertificate>> pairs = Collections.unmodifiableList(serverCerts);
            return new ResourceContext(tlsClient, h, pairs);
        }
        StreamHttpClientConnection conn = new StreamHttpClientConnection(h.getInputStream(), h.getOutputStream());
        HttpContext ctx = new BasicHttpContext();
        HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
        BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("GET", resource);
        HttpRequestHelper.setDefaultHeader(req, url);
        req.setHeader("Accept", "text/xml, */*;q=0.8");
        req.setHeader("Accept-Charset", "utf-8, *;q=0.8");
        setCookieHeader(req, cManager, url);
        HttpUtils.dumpHttpRequest(LOG, req);
        LOG.debug("Sending HTTP request.");
        HttpResponse response = httpexecutor.execute(req, conn, ctx);
        storeCookies(response, cManager, url);
        LOG.debug("HTTP response received.");
        StatusLine status = response.getStatusLine();
        int statusCode = status.getStatusCode();
        String reason = status.getReasonPhrase();
        HttpUtils.dumpHttpResponse(LOG, response, null);
        HttpEntity entity = null;
        boolean finished = false;
        if (TR03112Utils.isRedirectStatusCode(statusCode)) {
            Header[] headers = response.getHeaders("Location");
            if (headers.length > 0) {
                String uri = headers[0].getValue();
                url = new URL(uri);
            } else {
                // FIXME: refactor exception handling
                throw new ResourceException(MISSING_LOCATION_HEADER);
            }
        } else if (statusCode >= 400) {
            // according to the HTTP RFC, codes greater than 400 signal errors
            LOG.debug("Received a result code {} '{}' from server.", statusCode, reason);
            throw new InvalidResultStatus(LANG.translationForKey(INVALID_RESULT_STATUS, statusCode, reason));
        } else {
            if (verifyResult == CertificateValidator.VerifierResult.CONTINUE) {
                throw new InvalidAddressException(INVALID_REFRESH_ADDRESS_NOSOP);
            } else {
                conn.receiveResponseEntity(response);
                entity = response.getEntity();
                finished = true;
            }
        }
        // follow next redirect or finish?
        if (finished) {
            assert (entity != null);
            ResourceContext result = new ResourceContext(tlsClient, h, serverCerts);
            LimitedInputStream is = new LimitedInputStream(entity.getContent());
            result.setStream(is);
            return result;
        } else {
            h.close();
            return getStreamInt(url, v, serverCerts, maxRedirects);
        }
    } catch (URISyntaxException ex) {
        throw new IOException(LANG.translationForKey(FAILED_PROXY), ex);
    } catch (HttpException ex) {
        // don't translate this, it is handled in the ActivationAction
        throw new IOException("Invalid HTTP message received.", ex);
    }
}
Also used : HttpRequestExecutor(org.openecard.apache.http.protocol.HttpRequestExecutor) HttpEntity(org.openecard.apache.http.HttpEntity) BasicHttpContext(org.openecard.apache.http.protocol.BasicHttpContext) LimitedInputStream(org.openecard.common.io.LimitedInputStream) TlsClientProtocol(org.openecard.bouncycastle.tls.TlsClientProtocol) URISyntaxException(java.net.URISyntaxException) ClientCertTlsClient(org.openecard.crypto.tls.ClientCertTlsClient) StreamHttpClientConnection(org.openecard.transport.httpcore.StreamHttpClientConnection) URL(java.net.URL) TlsCrypto(org.openecard.bouncycastle.tls.crypto.TlsCrypto) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) HttpException(org.openecard.apache.http.HttpException) CookieManager(org.openecard.transport.httpcore.cookies.CookieManager) JavaSecVerifier(org.openecard.crypto.tls.verify.JavaSecVerifier) InvalidResultStatus(org.openecard.transport.httpcore.InvalidResultStatus) Pair(org.openecard.common.util.Pair) BasicHttpEntityEnclosingRequest(org.openecard.apache.http.message.BasicHttpEntityEnclosingRequest) BasicHttpContext(org.openecard.apache.http.protocol.BasicHttpContext) HttpContext(org.openecard.apache.http.protocol.HttpContext) ClientCertDefaultTlsClient(org.openecard.crypto.tls.ClientCertDefaultTlsClient) HttpResponse(org.openecard.apache.http.HttpResponse) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) IOException(java.io.IOException) StatusLine(org.openecard.apache.http.StatusLine) Header(org.openecard.apache.http.Header) DynamicAuthentication(org.openecard.crypto.tls.auth.DynamicAuthentication) InvalidAddressException(org.openecard.binding.tctoken.ex.InvalidAddressException) Socket(java.net.Socket) DynamicContext(org.openecard.common.DynamicContext)

Example 2 with ClientCertDefaultTlsClient

use of org.openecard.crypto.tls.ClientCertDefaultTlsClient in project open-ecard by ecsec.

the class TlsConnectionHandler method setUpClient.

public void setUpClient() throws ConnectionError {
    try {
        TCTokenType token = tokenRequest.getTCToken();
        String cardType = null;
        if (handle != null) {
            if (handle.getRecognitionInfo() != null) {
                cardType = handle.getRecognitionInfo().getCardType();
            }
            if (cardType == null) {
                cardType = tokenRequest.getCardType();
            }
        }
        // eID servers usually have problems with sni, so disable it for them
        // TODO: check occasionally if this still holds
        boolean doSni = !"http://bsi.bund.de/cif/npa.xml".equals(cardType);
        sessionId = token.getSessionIdentifier();
        serverAddress = new URL(token.getServerAddress());
        String serverHost = serverAddress.getHost();
        if (Boolean.valueOf(OpenecardProperties.getProperty("legacy.session"))) {
            serverAddress = fixServerAddress(serverAddress, sessionId);
        }
        // extract connection parameters from endpoint
        hostname = serverAddress.getHost();
        port = serverAddress.getPort();
        if (port == -1) {
            port = serverAddress.getDefaultPort();
        }
        resource = serverAddress.getFile();
        resource = resource.isEmpty() ? "/" : resource;
        String secProto = token.getPathSecurityProtocol();
        // use same channel as demanded in TR-03124 sec. 2.4.3
        if (isSameChannel()) {
            tlsClient = tokenRequest.getTokenContext().getTlsClient();
            if (tlsClient instanceof ClientCertDefaultTlsClient) {
                ((ClientCertDefaultTlsClient) tlsClient).setEnforceSameSession(true);
            }
        } else {
            // kill open channel in tctoken request, it is not needed anymore
            if (tokenRequest.getTokenContext() != null) {
                tokenRequest.getTokenContext().closeStream();
            }
            // determine TLS version to use
            ProtocolVersion version = ProtocolVersion.TLSv12;
            ProtocolVersion minVersion = ProtocolVersion.TLSv12;
            switch(secProto) {
                case "urn:ietf:rfc:5246":
                    // no changes
                    break;
                case "urn:ietf:rfc:4279":
                    minVersion = ProtocolVersion.TLSv11;
                    break;
            }
            // Set up TLS connection
            DynamicAuthentication tlsAuth = new DynamicAuthentication(serverHost);
            TlsCrypto crypto = new BcTlsCrypto(ReusableSecureRandom.getInstance());
            switch(secProto) {
                case "urn:ietf:rfc:4279":
                    {
                        byte[] psk = token.getPathSecurityParameters().getPSK();
                        TlsPSKIdentity pskId = new BasicTlsPSKIdentity(sessionId, psk);
                        tlsClient = new ClientCertPSKTlsClient(crypto, pskId, serverHost, doSni);
                        tlsClient.setClientVersion(version);
                        tlsClient.setMinimumVersion(minVersion);
                        break;
                    }
                case "urn:ietf:rfc:5246":
                    {
                        // use a smartcard for client authentication if needed
                        tlsAuth.setCredentialFactory(makeSmartCardCredential());
                        tlsClient = new ClientCertDefaultTlsClient(crypto, serverHost, doSni);
                        tlsClient.setClientVersion(version);
                        tlsClient.setMinimumVersion(minVersion);
                        // add PKIX verifier
                        if (verifyCertificates) {
                            tlsAuth.addCertificateVerifier(new JavaSecVerifier());
                        }
                        break;
                    }
                default:
                    throw new ConnectionError(UNKNOWN_SEC_PROTOCOL, secProto);
            }
            // make sure nobody changes the server when the connection gets reestablished
            tlsAuth.addCertificateVerifier(new SameCertVerifier());
            // save eService certificate for use in EAC
            tlsAuth.addCertificateVerifier(new SaveEServiceCertHandler());
            // set the authentication class in the tls client
            tlsClient.setAuthentication(tlsAuth);
        }
    } catch (MalformedURLException ex) {
        throw new ConnectionError(MALFORMED_URL, ex, "ServerAddress");
    }
}
Also used : TCTokenType(generated.TCTokenType) ClientCertPSKTlsClient(org.openecard.crypto.tls.ClientCertPSKTlsClient) MalformedURLException(java.net.MalformedURLException) ClientCertDefaultTlsClient(org.openecard.crypto.tls.ClientCertDefaultTlsClient) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) ProtocolVersion(org.openecard.bouncycastle.tls.ProtocolVersion) URL(java.net.URL) TlsCrypto(org.openecard.bouncycastle.tls.crypto.TlsCrypto) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) BasicTlsPSKIdentity(org.openecard.bouncycastle.tls.BasicTlsPSKIdentity) SameCertVerifier(org.openecard.crypto.tls.verify.SameCertVerifier) TlsPSKIdentity(org.openecard.bouncycastle.tls.TlsPSKIdentity) BasicTlsPSKIdentity(org.openecard.bouncycastle.tls.BasicTlsPSKIdentity) DynamicAuthentication(org.openecard.crypto.tls.auth.DynamicAuthentication) JavaSecVerifier(org.openecard.crypto.tls.verify.JavaSecVerifier)

Example 3 with ClientCertDefaultTlsClient

use of org.openecard.crypto.tls.ClientCertDefaultTlsClient in project open-ecard by ecsec.

the class TlsConnectionHandler method setUpClient.

public void setUpClient() throws InvalidTCTokenElement {
    try {
        sessionId = token.getSessionIdentifier();
        serverAddress = new URL(token.getServerAddress());
        String serverHost = serverAddress.getHost();
        // extract connection parameters from endpoint
        hostname = serverAddress.getHost();
        port = serverAddress.getPort();
        if (port == -1) {
            port = serverAddress.getDefaultPort();
        }
        resource = serverAddress.getFile();
        resource = resource.isEmpty() ? "/" : resource;
        String secProto = token.getPathSecurityProtocol();
        // determine TLS version to use
        ProtocolVersion version = ProtocolVersion.TLSv12;
        ProtocolVersion minVersion = ProtocolVersion.TLSv12;
        switch(secProto) {
            case "urn:ietf:rfc:5246":
            case "http://ws.openecard.org/pathsecurity/tlsv12-with-pin-encryption":
                // no changes
                break;
        }
        // Set up TLS connection
        DynamicAuthentication tlsAuth = new DynamicAuthentication(serverHost);
        switch(secProto) {
            case "urn:ietf:rfc:5246":
            case "http://ws.openecard.org/pathsecurity/tlsv12-with-pin-encryption":
                {
                    // use a smartcard for client authentication if needed
                    TlsCrypto crypto = new BcTlsCrypto(ReusableSecureRandom.getInstance());
                    tlsClient = new ClientCertDefaultTlsClient(crypto, serverHost, true);
                    tlsClient.setClientVersion(version);
                    tlsClient.setMinimumVersion(minVersion);
                    // add PKIX verifier
                    if (ChipGatewayProperties.isValidateServerCert()) {
                        tlsAuth.addCertificateVerifier(new CGJavaSecVerifier());
                    } else {
                        LOG.warn("Skipping server certificate validation of the ChipGateway server.");
                    }
                    break;
                }
            default:
                throw new InvalidTCTokenElement(ELEMENT_VALUE_INVALID, "PathSecurity-Protocol");
        }
        // make sure nobody changes the server when the connection gets reestablished
        tlsAuth.addCertificateVerifier(new SameCertVerifier());
        // set the authentication class in the tls client
        tlsClient.setAuthentication(tlsAuth);
    } catch (MalformedURLException ex) {
        throw new InvalidTCTokenElement(MALFORMED_URL, "ServerAddress");
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) InvalidTCTokenElement(org.openecard.addons.cg.ex.InvalidTCTokenElement) SameCertVerifier(org.openecard.crypto.tls.verify.SameCertVerifier) ClientCertDefaultTlsClient(org.openecard.crypto.tls.ClientCertDefaultTlsClient) DynamicAuthentication(org.openecard.crypto.tls.auth.DynamicAuthentication) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) ProtocolVersion(org.openecard.bouncycastle.tls.ProtocolVersion) URL(java.net.URL) TlsCrypto(org.openecard.bouncycastle.tls.crypto.TlsCrypto) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto)

Example 4 with ClientCertDefaultTlsClient

use of org.openecard.crypto.tls.ClientCertDefaultTlsClient in project open-ecard by ecsec.

the class HttpConnectProxy method connectSocket.

private Socket connectSocket() throws IOException {
    // Socket object connecting to proxy
    Socket sock = new Socket();
    SocketAddress addr = new InetSocketAddress(proxyHost, proxyPort);
    sock.setKeepAlive(true);
    // this is pretty much, but not a problem, as this only shifts the responsibility to the server
    sock.setSoTimeout(5 * 60 * 1000);
    sock.connect(addr, 60 * 1000);
    // evaluate scheme
    if ("HTTPS".equals(proxyScheme)) {
        TlsCrypto crypto = new BcTlsCrypto(ReusableSecureRandom.getInstance());
        ClientCertDefaultTlsClient tlsClient = new ClientCertDefaultTlsClient(crypto, proxyHost, true);
        DynamicAuthentication tlsAuth = new DynamicAuthentication(proxyHost);
        if (proxyValidate) {
            CertificateVerifier cv = new CertificateVerifierBuilder().and(new HostnameVerifier()).and(new KeyLengthVerifier()).and(new JavaSecVerifier()).build();
            tlsAuth.setCertificateVerifier(cv);
        }
        tlsClient.setAuthentication(tlsAuth);
        TlsClientProtocol proto = new TlsClientProtocol(sock.getInputStream(), sock.getOutputStream());
        proto.connect(tlsClient);
        // wrap socket
        Socket tlsSock = new SocketWrapper(sock, proto.getInputStream(), proto.getOutputStream());
        return tlsSock;
    } else {
        return sock;
    }
}
Also used : InetSocketAddress(java.net.InetSocketAddress) TlsClientProtocol(org.openecard.bouncycastle.tls.TlsClientProtocol) ClientCertDefaultTlsClient(org.openecard.crypto.tls.ClientCertDefaultTlsClient) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) CertificateVerifierBuilder(org.openecard.crypto.tls.verify.CertificateVerifierBuilder) KeyLengthVerifier(org.openecard.crypto.tls.verify.KeyLengthVerifier) TlsCrypto(org.openecard.bouncycastle.tls.crypto.TlsCrypto) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) HostnameVerifier(org.openecard.crypto.tls.verify.HostnameVerifier) CertificateVerifier(org.openecard.crypto.tls.CertificateVerifier) DynamicAuthentication(org.openecard.crypto.tls.auth.DynamicAuthentication) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) Socket(java.net.Socket) JavaSecVerifier(org.openecard.crypto.tls.verify.JavaSecVerifier) SocketWrapper(org.openecard.crypto.tls.SocketWrapper)

Aggregations

TlsCrypto (org.openecard.bouncycastle.tls.crypto.TlsCrypto)4 BcTlsCrypto (org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto)4 ClientCertDefaultTlsClient (org.openecard.crypto.tls.ClientCertDefaultTlsClient)4 DynamicAuthentication (org.openecard.crypto.tls.auth.DynamicAuthentication)4 URL (java.net.URL)3 JavaSecVerifier (org.openecard.crypto.tls.verify.JavaSecVerifier)3 MalformedURLException (java.net.MalformedURLException)2 Socket (java.net.Socket)2 ProtocolVersion (org.openecard.bouncycastle.tls.ProtocolVersion)2 TlsClientProtocol (org.openecard.bouncycastle.tls.TlsClientProtocol)2 SameCertVerifier (org.openecard.crypto.tls.verify.SameCertVerifier)2 TCTokenType (generated.TCTokenType)1 IOException (java.io.IOException)1 InetSocketAddress (java.net.InetSocketAddress)1 SocketAddress (java.net.SocketAddress)1 URISyntaxException (java.net.URISyntaxException)1 InvalidTCTokenElement (org.openecard.addons.cg.ex.InvalidTCTokenElement)1 Header (org.openecard.apache.http.Header)1 HttpEntity (org.openecard.apache.http.HttpEntity)1 HttpException (org.openecard.apache.http.HttpException)1