2

I'm using the iPhoneHTTPServer sample into my project for using HTTPServer, and host a .plist file with a .ipa to simulate an ad-hoc deployment.

As you may know, since iOS7, the server which hosts files must be secured, and so I'm trying to use a SSL authentication, but it failed.

First, the server seems to start correctly, but it failed when I'm trying to access to my server like this:

NSURL *plistUrl = [NSURL URLWithString:@"itms-services://?action=download-manifest&url=https://localhost:8080/TestMAJ2.plist"];
[[UIApplication sharedApplication] openURL:plistUrl];

I have this error :

NSAssert(NO, @"Security option unavailable - kCFStreamSSLLevel" @" - You must use GCDAsyncSocketSSLProtocolVersionMin & GCDAsyncSocketSSLProtocolVersionMax");

How can I bypass this error? I was trying to removed the kCFStreamSSLLevel of the TLS settings (why not ? ^^), but the connection still don't work, I've got a popup with "Unable to connect to localhost" or something like that ...

About the SSL authentication, the DDKeychain class from the sample was not good because it's Mac's API, so I use this code: How to make iPhoneHTTPServer secure server, and the certificate come from Keychain Access, and it's the certificate that I used for signing my app. Maybe it's not the correct certificate ? Or the correct piece of code ? Do you know a very simple example of using SecureHTTPServer in iOS?

Community
  • 1
  • 1
Christophe Gigax
  • 3,211
  • 4
  • 25
  • 37
  • Nobody for my problem ? – Christophe Gigax Sep 03 '14 at 08:16
  • use `[sslSettings setObject:[NSNumber numberWithInteger:2] forKey:GCDAsyncSocketSSLProtocolVersionMin]; [sslSettings setObject:[NSNumber numberWithInteger:2] forKey:GCDAsyncSocketSSLProtocolVersionMax];` to bypass this error. Basically this sets the TLS version to 2 – bikram990 Jul 02 '15 at 10:40

1 Answers1

0

I have the SSL certificate working perfectly with a .html file. I am having problems with the .manifest and the .ipa files.

What I did for the SSL is creating MyHTTPConnection class that implements the following:

- (NSArray *)sslIdentityAndCertificates
{
   SecIdentityRef identityRef = NULL;
   SecCertificateRef certificateRef = NULL;
   SecTrustRef trustRef = NULL;
   NSString *thePath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"pfx"];
   NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
   CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
   CFStringRef password = CFSTR("test123");
   const void *keys[] = { kSecImportExportPassphrase };
   const void *values[] = { password };
   CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);

   OSStatus securityError = errSecSuccess;
   securityError =  SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
   if (securityError == 0) {
       CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
       const void *tempIdentity = NULL;
       tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);
       identityRef = (SecIdentityRef)tempIdentity;
       const void *tempTrust = NULL;
       tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
       trustRef = (SecTrustRef)tempTrust;
   } else {
       NSLog(@"Failed with error code %d",(int)securityError);
       return nil;
  }

   SecIdentityCopyCertificate(identityRef, &certificateRef);
   NSArray *result = [[NSArray alloc] initWithObjects:(__bridge id)identityRef, (__bridge id)certificateRef, nil];

   return result;
}

Then in the App Delegate I just setted this custom connection class to the httpServer:

 [httpServer setConnectionClass:[MyHTTPConnection class]];

The last thing that you need to do is to add the server.pfx certificate to the bundle. I created the certificate following this tutorial. I just did until you have the server.crt file. Then I converted it to pfx12 in this website. I did this because p12 certificate was not working, I was having this problem.

Chris, could you edit your entry explaining a little bit how you did the manifest thing. I want to do exactly the same as you but I am having troubles with the URLs that you need to open.

Community
  • 1
  • 1
Nicolas Yuste
  • 673
  • 9
  • 15
  • I'm sorry I do not work order on the project anymore. The .manifest that you speak about is the .plist file That You put on your server? Xcode generates all of this stuff for you , and you should have something like this : http://pastebin.com/8kx9fW2L – Christophe Gigax Jan 19 '15 at 12:54
  • I know. I got everything working on a webServer. The problem is that I would like to be able to install the app from the device itself. For that I am downloading the .ipa and the manifest.plist into the device. Then I need to create a web server locally so Safari can get to that downloaded files. But I am getting in trouble with SSL and .plist files. Thanks anyway. – Nicolas Yuste Jan 19 '15 at 18:59
  • I was facing the exact same problem but nowadays I didn't found any solution, sorry ... – Christophe Gigax Jan 20 '15 at 11:02
  • @nicoyuste Hello. Did you find a solution for your issue? I have the same problem. Is it possible to implement it? – Olexii Muraviov Dec 28 '17 at 10:48
  • Hello. Yes, I did find a solution for this and it is possible. Sadly, I did the project a while ago and I do not remember anymore how I solved all the problems. :( – Nicolas Yuste Dec 29 '17 at 08:47