2010-02-10 9 views
8

Ich schreibe eine Anwendung, die NStreams SSL-Funktionen auf dem iPhone verwendet. Ich weiß, dass SSL funktioniert, weil ich Server direkt über SSL verbinden kann.
Ich habe ein Problem festgestellt, wo Protokolle, die Starttls verwenden erfordern, dass ich auf dem Socket mit ungesicherten kommunizieren, senden Sie den Befehl starttls und dann wiederverwenden den gleichen Socket für SSL. Soweit ich weiß, können nstream-Verbindungen nicht wiederverwendet werden und ich kann kein SSL auf ihnen starten, nachdem ich die Verbindung geöffnet habe.NStream SSL auf verwendetem Socket

Ich überlegte, meinen eigenen Socket zu erstellen, manuell darüber zu kommunizieren und dann einen NStream unter Verwendung des vorhandenen Sockets einzurichten und SSL auf diese Weise zu starten. Es scheint jedoch, dass die Kommunikation auf dem Socket es in einem Zustand platziert, in dem ich SSL darauf starten kann. Jeder Versuch, den Socket für NStream zu verwenden, führt zu einem Fehler.

Irgendwelche Gedanken?

+0

Haben Sie versucht, setProperty Aufruf: forKey: mit den entsprechenden Sicherheitskonstanten auf einem bereits geöffneten NSSocket? Ich glaube, der zugrunde liegende SecureTransport-Code unterstützt das Wechseln zu TLS/SSL über eine unverschlüsselte erste Verbindung. –

+0

Also habe ich das herausgefunden. Sie sollten CFsockets und nicht NSockets verwenden und dann die SSL nach der Verbindung anwenden, obwohl die Dokumentation besagt, dass Sie das nicht tun können, wird es eine sichere Verbindung richtig aushandeln. – anurodhp

+0

gibt es keine "NS Sockets" – user102008

Antwort

7

Dies ist der richtige Weg, dies zu tun. während dies geschieht (Einstellung der Eigenschaft nach Socket-Verbindung) ist nicht dokumentiert, dies ist Code direkt von meinem Monal Xmpp-Client und Apple hat mir nie Probleme im App Store gegeben.

NSInputStream *iStream; 
NSOutputStream *oStream; 


CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)server, port, &iStream, &oStream); 


[iStream open]; 
    [oStream open]; 

Sobald die Verbindung geöffnet wurde und Sie erhalten NSStreamEventOpenCompleted und die STARTTLS-Befehl wurde an den Host vom Client gesendet:

NSDictionary *settings = [ [NSDictionary alloc ] 
            initWithObjectsAndKeys: 
            [NSNumber numberWithBool:YES], @"kCFStreamSSLAllowsExpiredCertificates", 
            [NSNumber numberWithBool:YES], @"kCFStreamSSLAllowsExpiredRoots", 
            [NSNumber numberWithBool:YES], @"kCFStreamSSLAllowsAnyRoot", 
            [NSNumber numberWithBool:NO], @"kCFStreamSSLValidatesCertificateChain", 
            [NSNull null],@"kCFStreamSSLPeerName", 
            @"kCFStreamSocketSecurityLevelNegotiatedSSL", 
            @"kCFStreamSSLLevel", 
            nil ]; 
     CFReadStreamSetProperty((CFReadStreamRef)iStream, 
           @"kCFStreamPropertySSLSettings", (CFTypeRef)settings); 
     CFWriteStreamSetProperty((CFWriteStreamRef)oStream, 
           @"kCFStreamPropertySSLSettings", (CFTypeRef)settings); 
+2

Es ist wahrscheinlich eine bessere Idee, die Konstanten zu verwenden, anstatt sie in Strings zu verpacken. Die Konstanten und Strings können in diesem Fall dasselbe Ergebnis liefern, aber das ist nicht immer so. Also, kCFStreamSSLLevel statt @ "kCFStreamSSLLevel". –

+0

Ich versuche, die CFReadStreamSetProperty in meiner iOS 7 App zu verwenden, aber Xcode 5.1.1 sagt mit "Keine passende Funktion für den Aufruf von 'CFReadStreamSetProperty' obwohl ich #import #import < CoreFoundation/CFStream.h> und ich fügte auch CFNetwork.framework und CoreFoundation.framework.Jeder Hit, wie das zu beheben? –