[ 
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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to