Archived

This forum has been archived. Please start a new discussion on GitHub.

IceTouch with SSL - "certificate validation failed (result=5)"

Hi,

Does anyone have experience with SSL on IceTouch here? We are trying to connect an iPhone client to a C# backend server using iceSSL plugin for the backend and iceTouch on the iPhone.

We have created a "ca_cert.pem" and a "cert.pks" (with some password) for the C# backend. Further, we converted the "ca_cert.pem" into a "ca_cert.der" file using the openssl tool for the iPhone. We are using the "ca_cert.der" and "cert.pks" files for the iPhone client. When we try to connect the iPhone client to the backend, we get the following exception:

2012-07-18 18:12:58.106 XXXXX[3338:15803] E XXXXX:IceConnectorToBackend.m:69:-[IceConnectorToBackend initWithDelegate:] Ice connection exception Transceiver.cpp:764: Ice::SecurityException:
security exception:
certificate validation failed (result = 5)


The exception only occurs after the frontend contacts the C# backend.

We have the same setup working with an Android client without any issues. Although, for the android client we converted both the ca_cert.pem and cert.pfx files into "BKS" formats as ca_cer.bks and cert.bks respectively.

Also, the Ice connection between C# backend and iPhone client is working fine without SSL turned ON.

We are using the latest version of Ice touch and the Xcode version 4.3.3 with iOS version 5.1. Further, we are currently testing using the iPhone simulator.

Any help in this regard will be greatly appreciated. Please tell me if you need any more information from our side.

thanks
sandeep

Comments

  • xdm
    xdm La Coruña, Spain
    Hi,

    Does it works when you use the certificates provided with IceTouch?

    Seems to me that you are using a server certificate with MD5 signature. That isn't supported for IceTouch, see:

    Release Notes - Ice Touch 1.2 - ZeroC

    The certificates provided in IceTouch demo uses sha256 signature algorithm.
  • You are right. We do use certificates with MD5 hashes. Will try with a sha256 hash and get back in case we have any further issues.

    Thanks
    sandeep
  • Hi,

    I apologize for the late response. We were able to work on this only now. We tried with sha256 signed certificates and we are still getting the same exception:


    Exception: Transceiver.cpp:764: Ice::SecurityException:
    security exception:
    certificate validation failed (result = 5)


    I researched on this exception and it seems that SecTrustEvaluate() in objc/src/Transports/Transceiver.cpp is causing this exception. The value of the result (=5) means that the function is giving a result of kSecTrustResultRecoverableTrustFailure . From this stackoverflow article ( http://stackoverflow.com/questions/5340937/continuously-getting-ksectrustresultrecoverabletrustfailure-while-trust-evaluati ), it seems one of the following is happening:

    1. the certificate is md5 hashed (IOS5)
    2. the server does not present the root and intermediate certificates
    3. the SecTrustSetAnchorCertificatesOnly(trust,YES) is set and the anchor certificate is only in the built in anchor certificates
    4. the certificate is expired

    I am sure that 1 and 4 are not true anymore. I tried to import the certificates to the keychain access of the my local mac to ensure that the certificate is indeed signed using sha256. Also I provided the keychain password as a property for IceSSL since I am using the simulator. I am still getting the same exception.
  • benoit
    benoit Rennes, France
    Hi,

    Did you check if SSL is working with the Ice Touch iPhone hello demo? You could try to use the Ice Touch demo certificates with your application and see if it works. If this doesn't provide any hints, the best would be to provide a small test case that we could use to reproduce the problem. You could for example try to reproduce the problem with the iPhone hello demo and a set of certificates leading to the same issue.

    Cheers,
    Benoit.
  • Hi

    We got it to work finally ! The problem was that I was using a ca_cert.p12 file as the truststore in our backend java codebase. Once I converted it to a ca_cert.jks file using the "keytool" program available on MAC/Linux, I can now connect my iOS frontend to the java backend.

    We have two different backends: a java backend and a C# backend. Earlier, I was testing with the MD5 signed certificates with the C# backend. When I converted to the sha256 signed certificates, I mistakenly tested with the java backend first. Now, both backends are able to connect to the iOS frontend through SSL.


    thanks
    sandeep
  • Just for future reference, I am listing the different types of certificates and different properties that worked for us. Please note that the certificates have to be signed using sha256. It is possible to generate the sha256 signed certificates using the iceca python script available in the ice source distribution. One change that is needed in the iceca script is to change the default_md format to sha256 instead of md5. For info on how to generate the certificates, please refer to Setting up a Certificate Authority - Ice 3.4 - ZeroC . The files generated by the iceca script will be of the form .pem, .pfx or .jks formats. However, you might need other formats for the certificates such as .der, or .bks. You can use a combination of the openssl, keytool and portecle tools for converting certificates of one form to another. The following are the types of certificates and IceSSL properties that are required to to get IceSSL working.

    For a C# ice end point, the files required are ca_cert.pem and cert.pfx
    The following are the properties that we set:


    initData.properties.setProperty("Ice.Plugin.IceSSL", @C:\Ice\lib\IceSSL.dll:IceSSL.PluginFactory);
    initData.properties.setProperty("IceSSL.DefaultDir", @C:\Ice\sha256IceCerts);
    initData.properties.setProperty("IceSSL.CertFile", "cert.pfx");
    initData.properties.setProperty("IceSSL.Password", "xxxxxx");
    initData.properties.setProperty("IceSSL.ImportCert.LocalMachine.AuthRoot", "ca_cert.pem");


    For a java end point, the files required are ca_cert.jks and cert.jks
    The following are the properties that we set:


    initData.properties.setProperty("Ice.Plugin.IceSSL", "IceSSL.PluginFactory");
    initData.properties.setProperty("IceSSL.DefaultDir", "/usr/share/tomcat7/webapps/portal/WEB-INF/keystore/sha256IceCerts");
    initData.properties.setProperty("IceSSL.Keystore", "cert.jks");
    initData.properties.setProperty("IceSSL.Truststore", "ca_cert.jks");
    initData.properties.setProperty("IceSSL.TruststorePassword", "xxxxxx");
    initData.properties.setProperty("IceSSL.Password", "xxxxxx");


    For an Android end point, the files required are ca_cert.bks and cert.bks
    The following are the properties that we set:


    initData.properties.setProperty("Ice.Plugin.IceSSL", "IceSSL.PluginFactory");
    initData.properties.setProperty("IceSSL.TruststoreType", "BKS");
    initData.properties.setProperty("IceSSL.TruststorePassword", "xxxxxxx");
    initData.properties.setProperty("IceSSL.Password", "xxxxxxx");
    initData.properties.setProperty("Ice.InitPlugins", "0");
    certStream = context.getResources().openRawResource(R.raw.cert);
    caStream = context.getResources().openRawResource(R.raw.ca_cert);
    IceSSL.Plugin plugin = (IceSSL.Plugin) communicator.getPluginManager().getPlugin("IceSSL");
    plugin.setKeystoreStream(certStream);
    plugin.setTruststoreStream(caStream);
    communicator.getPluginManager().initializePlugins();


    For an iOS end point, the files required are ca_cert.der and cert.pfx


    [initData.properties setProperty:@IceSSL.CheckCertName value:@"0"];
    [initData.properties setProperty:@IceSSL.CertAuthFile value:@ca_cert.der];
    [initData.properties setProperty:@IceSSL.CertFile value:@cert.pfx];
    [initData.properties setProperty:@IceSSL.Password value:@xxxxxxx];