3

I'm syncing my Mac application with my iPhone application using NSStream and am trying to encrypt the communication with SSL. I've tried to run CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings) on the iPhone side and CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings) on the Mac side when I set up the NSInputStream and NSOutputStream respectively. For the settings dictionary, I'm following the advice of http://iphonedevelopment.blogspot.com/2010/05/nsstream-tcp-and-ssl.html and ignoring the properties of the certificate. However, encrypting it in this way doesn't seem to work as the transfer does not go through - is there something else I need to do to get this functionality working?

Thanks!

EDIT: Here's some code:

On the Mac:

NSOutputStream *outStream;
[service getInputStream:nil outputStream:&outStream];
[outStream open];

[outStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL 
forKey:NSStreamSocketSecurityLevelKey];  

        NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
kCFNull,kCFStreamSSLPeerName, nil];

CFWriteStreamSetProperty((CFWriteStreamRef)outStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);

int bytes = [outStream write:[rawPacket bytes] maxLength:[rawPacket length]];
[outStream close];

On the iPhone:

CFReadStreamRef readStream;


NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"file"];

NSOutputStream *fileStream = [NSOutputStream outputStreamToFileAtPath:self.filePath append:NO];

[fileStream open];


CFStreamCreatePairWithSocket(NULL, fd, &readStream, NULL);

NSInputStream *networkStream = (NSInputStream *) readStream;

CFRelease(readStream);

[networkStream setProperty:(id)kCFBooleanTrue forKey:(NSString *)kCFStreamPropertyShouldCloseNativeSocket];

networkStream.delegate = self;
[networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[networkStream open];

[self.networkStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL 
                        forKey:NSStreamSocketSecurityLevelKey];

NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
kCFNull,kCFStreamSSLPeerName, nil];

CFReadStreamSetProperty((CFReadStreamRef)self.networkStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
PF1
  • 4,511
  • 14
  • 45
  • 76
  • "transfer does not go through"? Do you get any error? logs?? – prakash Aug 28 '11 at 09:05
  • @Prakash On the mac it writes "-1 bytes" and on the iPhone it stops the receive with status "Stream open error". – PF1 Sep 04 '11 at 22:08
  • 1
    @Prakash - one thing to mention here. If you plan to use SSL, you have to fullfil the export compliance for encryption! Even when using the built-in SSL functionality of iOS, you need to get an export compliance from the US government. Check this SO question : http://stackoverflow.com/questions/2128927/using-ssl-in-an-iphone-app-export-compliance – Chris Sep 09 '11 at 22:05
  • Can you post the code you're actually using to do this? – Evan Cordell Sep 10 '11 at 23:12
  • @Chris Thanks for the heads up! – PF1 Sep 11 '11 at 00:43
  • @Evan Just posted the code - thoughts? – PF1 Sep 11 '11 at 00:44

1 Answers1

1

I'm not sure exactly what your problem is. But there are several things that raise flags for me.

  1. It seems fishy that your Mac side only has an output stream and your iPhone side only has an input stream. I don't see how you can have an SSL handshake in a one-way stream like that, though it's possible that it's taken care of behind the scenes.
  2. You're attempting client-server communication between what, to me, seems to be two client applications. How is your Mac app serving an SSL certificate? Edit: I now see that your outputStream is based on some service object, so it's possible you're handling this and just not showing the code.
  3. A comment in the article you linked to suggests that when a stream writes "-1 bytes", there's a problem opening the output stream. So first you will need to resolve the issues on the Mac side before moving to the iPhone app (which I believe also has some problems).
  4. It doesn't look like your read stream on the iPhone side is properly created. All you do is declare it with CFReadStreamRef readStream;. I would look at the documentation to see how to properly create one.

All in all it seems like you're missing a lot of pieces, so hopefully some of these resources can help you get on track: Mac-iPhone communication with a python server, Apple's Bonjour documentation, and an answer on a related SO post with some good links.

Community
  • 1
  • 1
Evan Cordell
  • 4,068
  • 2
  • 27
  • 47