2010-02-10 10 views
8

Estoy escribiendo una aplicación que usa las funciones SSL de NSStream en el iphone. Sé que SSL funciona porque puedo conectar servidores directamente usando SSL.
He encontrado un problema donde los protocolos que usan starttls requieren que me comunique en el socket con no segura, envíe el comando starttls y luego reutilice el mismo socket para SSL. Por lo que sé, las conexiones nsstream no se pueden reutilizar y no puedo iniciar SSL en ellas después de haber abierto la conexión.NSStream SSL en el socket usado

Pensé en crear mi propio socket, comunicarme en él manualmente y luego configurar un NSstream usando el socket existente e iniciar SSL de esa manera. Sin embargo, parece que la comunicación en el socket lo coloca en un estado en el que no puedo iniciar SSL. Cualquier intento de usar el socket para nsstream produce un error.

¿Alguna idea?

+0

Ha intentado llamar setProperty: forKey: con las constantes de seguridad adecuadas en un NSSocket ya abierto? Creo que el código subyacente de SecureTransport admite el cambio a TLS/SSL desde una conexión inicial no encriptada. –

+0

Así que me di cuenta de esto. Debe usar CFsockets y no NSsockets y luego aplicar el SSL DESPUÉS de la conexión, aunque la documentación dice que no puede hacerlo, negociará correctamente una conexión segura. – anurodhp

+0

no existe tal cosa como "NSsockets" – user102008

Respuesta

7

Esta es la forma correcta de hacerlo. al hacer esto (establecer la propiedad después de la conexión del socket) no está documentado, este es código directamente de mi cliente xmpp de Monal y Apple nunca me ha dado ningún problema en la tienda de aplicaciones.

NSInputStream *iStream; 
NSOutputStream *oStream; 


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


[iStream open]; 
    [oStream open]; 

vez que la conexión se ha abierto y se obtiene NSStreamEventOpenCompleted y los StartTLS comando ha sido enviado al host desde el cliente:

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

Probablemente sea una mejor idea usar las constantes en lugar de envolverlas en cadenas; las constantes y las cadenas pueden evaluar el mismo resultado en este caso, pero eso no siempre es así. Por lo tanto, kCFStreamSSLLevel en lugar de @ "kCFStreamSSLLevel". –

+0

Estoy tratando de usar el CFReadStreamSetProperty en mi aplicación iOS 7, pero Xcode 5.1.1 me dice "No hay función de coincidencia para llamar a 'CFReadStreamSetProperty' aunque tengo #import #import < CoreFoundation/CFStream.h> y también agregué CFNetwork.framework y CoreFoundation.framework. ¿Alguna pregunta sobre cómo solucionarlo? –

Cuestiones relacionadas