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)