Fine grain X509 certificate checks and TrustManage

2019-08-05 12:41发布

问题:

I am trying to configure a https client in my android application that would perform fine grain checking on the certificate chain received from server.

More precisely I would like to check :

  • if the chain contains a given CA certificate (custom CA)
  • the value of the common name and the organization name of the end-of-chain certificate

I though this could be done by initializing a TrustManagerFactory with properly constructed CertPathTrustManagerParameters but the 2nd line of this code snippet:

TrustManagerFactory tmf = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

tmf.init(new CertPathTrustManagerParameters(pkixBuilderParameters));

throws the following Exception :

 Unsupported spec: javax.net.ssl.CertPathTrustManagerParameters@634b748. 
 Only android.security.net.config.RootTrustManagerFactorySpi$ApplicationConfigParameters supported.

From this post : https://security.stackexchange.com/questions/83372/what-is-the-difference-of-trustmanager-pkix-and-sunx509 I understand that Android JSSE provider may not support TrustManagerFactory initialization with CertPathTrustManagerParameters.

I would like to know if it is possible to initialize TrustManagerFactory with CertPathTrustManagerParameters on Android.

A back up solution for my problem is to initialize TrustManagerFactory with a KeyStore containing my CA certificate and to override checkServerTrusted(X509Certificate[] chain, String authType) function of the generated TrustManager adding checks on organization and common name.

Note :

Regardless of the algorithm specified when calling

 TrustManagerFactory tmf = TrustManagerFactory.getInstance(String algorithm)

the TrustManagerFactory object returned is always set with a RootTrustManagerFactorySpi as TrustManagerFactorySpi.

Then, the function

tmf.init(new CertPathTrustManagerParameters(pkixBuilderParameters))

calls the following function in RootTrustManagerFactorySpi:

@Override
public void engineInit(ManagerFactoryParameters spec)
        throws InvalidAlgorithmParameterException {
    if (!(spec instanceof ApplicationConfigParameters)) {
        throw new InvalidAlgorithmParameterException("Unsupported spec: " +  spec + ". Only "
                + ApplicationConfigParameters.class.getName() + " supported");

    }
    mApplicationConfig = ((ApplicationConfigParameters) spec).config;
}

This shows that, when initalized with ManagerFactoryParameters, the TrustManagerFactory only accepts ApplicationConfigParameters to be provided and rejects CertPathTrustManagerParameters (both are child class of ManagerFactoryParameters)