2010-02-10 11 views
8

Piszę aplikację korzystającą z funkcji SSL NSStream na iPhone. Wiem, że protokół SSL działa, ponieważ mogę bezpośrednio łączyć się z serwerami za pomocą protokołu SSL.
Napotkano na problem polegający na tym, że protokoły używające starttli wymagają ode mnie komunikacji w gnieździe niezabezpieczonym, wysłania polecenia starttls, a następnie ponownego użycia tego samego gniazda dla SSL. O ile wiem, połączenia nsstream nie mogą być ponownie użyte i nie mogę uruchomić protokołu SSL po ich otwarciu.SSL NSStream na używanym gnieździe

Pomyślałem o stworzeniu własnego gniazda, komunikacji na nim ręcznie, a następnie skonfigurowaniu NSstream przy użyciu istniejącego gniazda i uruchomieniu SSL w ten sposób. Jednak wydaje się, że komunikacja w gnieździe umieszcza go w stanie, w którym nie mogę uruchomić SSL. Każda próba użycia gniazda dla nsstream powoduje błąd.

Jakieś myśli?

+0

Czy próbowałeś dzwoniąc setProperty: forKey: z odpowiednich stałych zabezpieczeń na już otwartym NSSocket? Uważam, że podstawowy kod SecureTransport obsługuje przełączanie na TLS/SSL z niezaszyfrowanego połączenia początkowego. –

+0

Więc wymyśliłem to. Powinieneś użyć CFsockets, a nie NSsockets, a następnie zastosować SSL PO połączeniu, chociaż dokumentacja mówi, że nie możesz tego zrobić, to poprawnie wynegocjuje bezpieczne połączenie. – anurodhp

+0

Nie ma czegoś takiego jak "NSsockets" – user102008

Odpowiedz

7

To jest właściwy sposób, aby to zrobić. robiąc to (ustawiając właściwość po połączeniu przez gniazdo) jest nieudokumentowane, jest to kod bezpośrednio z mojego klienta xalp Monal i jabłko nigdy nie dało mi żadnych problemów w sklepie z aplikacjami.

NSInputStream *iStream; 
NSOutputStream *oStream; 


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


[iStream open]; 
    [oStream open]; 

Gdy połączenie zostało otwarte i masz NSStreamEventOpenCompleted i StartTLS polecenie zostało wysłane do hosta z klientem:

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

Lepiej jest używać stałych zamiast owijać je w ciągi; stałe i ciągi mogą w tym przypadku ocenić taki sam wynik, ale nie zawsze tak jest. Tak więc, kCFStreamSSLLevel zamiast @ "kCFStreamSSLLevel". –

+0

Próbuję użyć CFReadStreamSetProperty w mojej aplikacji iOS 7, ale Xcode 5.1.1 mówi "Brak pasującej funkcji dla połączenia z" CFReadStreamSetProperty ", chociaż mam #import #import < CoreFoundation/CFStream.h> i dodałem również CFNetwork.framework i CoreFoundation.framework. Dowolne trafienie, jak to naprawić? –

Powiązane problemy