2010-02-10 6 views
8

Sto scrivendo un'applicazione che utilizza le funzioni SSL di NSStream sull'iPhone. So che SSL sta funzionando perché posso collegare direttamente i server usando SSL.
Ho riscontrato un problema in cui i protocolli che utilizzano starttls mi richiedono di comunicare sul socket con unsecured, inviare il comando starttls e quindi riutilizzare lo stesso socket per SSL. Per quanto ne so, le connessioni nsstream non possono essere riutilizzate e non posso avviare SSL su di esse dopo aver aperto la connessione.SSL NSStream sulla presa utilizzata

Ho pensato di creare il mio socket, comunicarlo manualmente e quindi configurare un NSstream utilizzando il socket esistente e avviare SSL in questo modo. Tuttavia, sembra che la comunicazione sulla presa lo collochi in uno stato in cui non posso avviare SSL su di esso. Qualsiasi tentativo di utilizzare il socket per nsstream genera un errore.

Qualche idea?

+0

Hai provato chiamare setProperty: Forkey: con le costanti di protezione appropriati su un NSSocket già aperto? Credo che il codice SecureTransport sottostante supporti il ​​passaggio a TLS/SSL da una connessione iniziale non crittografata. –

+0

Quindi ho capito. Dovresti utilizzare CFsocket e non NSsocket e quindi applicare SSL dopo la connessione, anche se la documentazione dice che non puoi farlo, negozia correttamente una connessione sicura. – anurodhp

+0

non esiste "NSsockets" – user102008

risposta

7

Questo è il modo corretto per farlo. mentre facendo questo (impostando la proprietà dopo la connessione socket) non è documentato, questo è il codice direttamente dal mio client xmpp di Monal e Apple non mi ha mai dato problemi nell'app store.

NSInputStream *iStream; 
NSOutputStream *oStream; 


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


[iStream open]; 
    [oStream open]; 

volta che la connessione è stata aperta e si ottiene NSStreamEventOpenCompleted ei STARTTLS comando è stato inviato per l'host dal client:

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

Probabilmente è un'idea migliore usare le costanti invece di avvolgerle nelle stringhe; le costanti e le stringhe possono valutare lo stesso risultato in questo caso, ma non è sempre così. Quindi, kCFStreamSSLLevel invece di @ "kCFStreamSSLLevel". –

+0

che sto cercando di utilizzare il CFReadStreamSetProperty nei miei iOS 7 app, ma Xcode 5.1.1 dice mit "No funzione di corrispondenza per la chiamata a 'CFReadStreamSetProperty' anche se ho #import #import < CoreFoundation/CFStream.h> e ho aggiunto anche CFNetwork.framework e CoreFoundation.framework. Qualche hit come risolvere il problema? –