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);
}
}
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");
}
}
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");
}
}
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;
}
}
Aggregations