You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "Mikhail Golubev (JIRA)" <ji...@apache.org> on 2014/01/20 16:48:19 UTC

[jira] [Comment Edited] (HTTPCLIENT-1449) X509HostnameVerifier API is too restrictive

    [ https://issues.apache.org/jira/browse/HTTPCLIENT-1449?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13876526#comment-13876526 ] 

Mikhail Golubev edited comment on HTTPCLIENT-1449 at 1/20/14 3:46 PM:
----------------------------------------------------------------------

Hi, Oleg.

Well, it's exactly what I'm doing now. I think you're suggesting something like this (correct me if I'm wrong)

{code:title=DelegatingHostnameVerifier.java}
import org.apache.http.conn.ssl.X509HostnameVerifier;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.security.cert.X509Certificate;

public class DelegatingHostnameVerifier implements X509HostnameVerifier {

  private final X509HostnameVerifier verifier;

  public DelegatingHostnameVerifier(X509HostnameVerifier verifier) {
    this.verifier = verifier;
  }

  @Override
  public boolean verify(String s, SSLSession session) {
    return verifier.verify(s, session);
  }

  @Override
  public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
    // never called
    verifier.verify(host, cns, subjectAlts);
  }

  @Override
  public void verify(String host, X509Certificate cert) throws SSLException {
    // never called as well
    try {
      verifier.verify(host, cert);
    }
    catch (SSLException e) {
      if (!userAcceptsCertificate()) {
        throw e;
      }
    }
  }

  @Override
  public void verify(String host, SSLSocket ssl) throws IOException {
    verifier.verify(host, ssl);
  }

  private boolean userAcceptsCertificate() {
    ...
  }
}
{code}

Because call sequence starts from method {{void verify(String host, SSLSocket ssl)}} and I need certificate instance, I should intercept verification result there and reproduce all the logic, related to extraction X509Certificate from SSLSocket. The same applies to original {{boolean verify(String s, SSLSession session)}} from {{javax.net.ssl.HostnameVerifier}} (but I'm not sure here). Isn't subclassing from {{AbstractVerifier}} with overriding only {{void verify(String host, X509Certificate cert)}} and delegating there to {{BrowserCompatHostnameVerifier}} would be much convenient approach?



was (Author: east825):
Hi, Oleg.

Well, it's exactly what I'm doing now. I think you're suggesting something like this (correct me if I'm wrong)

{code:title=DelegatingHostnameVerifier.java}
import org.apache.http.conn.ssl.X509HostnameVerifier;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.security.cert.X509Certificate;

public class DelegatingHostnameVerifier implements X509HostnameVerifier {

  private final X509HostnameVerifier verifier;

  public DelegatingHostnameVerifier(X509HostnameVerifier verifier) {
    this.verifier = verifier;
  }

  @Override
  public boolean verify(String s, SSLSession session) {
    return verifier.verify(s, session);
  }

  @Override
  public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
    // never called
    verifier.verify(host, cns, subjectAlts);
  }

  @Override
  public void verify(String host, X509Certificate cert) throws SSLException {
    // never called as well
    try {
      verifier.verify(host, cert);
    }
    catch (SSLException e) {
      if (!userAcceptsCertificate()) {
        throw e;
      }
    }
  }

  @Override
  public void verify(String host, SSLSocket ssl) throws IOException {
    verifier.verify(host, ssl);
  }

  private boolean userAcceptsCertificate() {
    ...
  }
}
{code}

Because call sequence starts from method {{void verify(String host, SSLSocket ssl)}} and I need certificate instance, I should intercept verification result there and reproduce all the logic, related to extraction X509Certificate from SSLSocket. The same applies to original {{boolean verify(String s, SSLSession session)}} from {{javax.net.ssl.HostnameVerifier}} (but I'm not sure here). Isn't subclassing from {{AbstractVerifier}} and only delegating to {{BrowserCompatHostnameVerifier}} in  {{void verify(String host, X509Certificate cert)}} would be much convenient approach?


> X509HostnameVerifier API is too restrictive
> -------------------------------------------
>
>                 Key: HTTPCLIENT-1449
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1449
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>    Affects Versions: 4.3.1
>            Reporter: Mikhail Golubev
>            Priority: Minor
>
> I want to customize hostname verification process by creating custom X509HostnameVerifier, which first try to use BrowserCompatHostnameVerifier strategy to check hostname and then, if it fails, asks user directly, whether such certificate can be accepted. As I understand, this verifier then can be supplied to e.g. HttpClientBuilder#setHostnameVerifier.
> But how should I achieve this? I can't extend BrowserCompatHostnameVerifier, because all its methods is final or package-private. Extending AbstractVerifier also makes no sense, because its only overridable method  is verify(String, String[], String[]) and it gives me no access to certificate itself, which I need for user dialog. On the other hand, method verify(String host, X509Certificate cert) is the perfect extension point for me, but it's declared final. I really don't like to implement X509HostnameVerifier and then copy half of the AbstractVerifier in it. May be I'm missing some other way to intercept hostname verification?



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org