2012-11-23 12 views
6

Używam CFStream/NSStream do tworzenia połączeń http. Chcę być w stanie wykryć, że uścisk dłoni SSL nie powiedzie się z trzech przypadkach:Jak skonfigurować CFStream (lub NSStream) do uzgadniania SSL?

  • przypadek A: Serwer nie jest zaufany
  • przypadek B: serwer jest zaufany, ale prosi certyfikatu klienta
  • Przypadek C: serwer nie jest zaufany i prosi certyfikatu klienta

Dziś nie robiąc anithing na właściwości SSL mojego CFStream, otrzymuję:

  • przypadek A: Błąd -9807
  • przypadek B: nie błąd, ale serwer odmawia połączenia (błąd 500)
  • sprawa C: error 9807

Czy istnieje sposób, aby skonfigurować CFStream prawidłowo odróżnić te 3 przypadki? Lub mieć pewne wywołania zwrotne podczas uzgadniania SSL?

Dzięki za pomoc.

Odpowiedz

4

Jakiś czas temu wpadłem w samo z CFSockets z wykorzystaniem protokołu SSL. CFStream obsługuje wszystkie rzeczy związane z handshake. Napisałem mały dodatek do klasy dla NSStream (kod bazowy pochodzi z Apple, nie ma już linku, jeśli go znajdę, dodam go). To właśnie dla mnie zadziałało.

Interfejs

@interface NSStream (FSNetworkAdditions) 

+ (void)qNetworkAdditions_getStreamsToHostNamed:(NSString *)hostName 
              port:(NSInteger)port 
            inputStream:(out NSInputStream **)inputStreamPtr 
            outputStream:(out NSOutputStream **)outputStreamPtr; 

@end 

i realizacja

#import "FSNetworkAdditions.h" 

@implementation NSStream (FSNetworkAdditions) 

+ (void)qNetworkAdditions_getStreamsToHostNamed:(NSString *)hostName 
              port:(NSInteger)port 
            inputStream:(out NSInputStream **)inputStreamPtr 
            outputStream:(out NSOutputStream **)outputStreamPtr 
{ 
    CFReadStreamRef  readStream; 
    CFWriteStreamRef writeStream; 

    assert(hostName != nil); 
    assert((port > 0) && (port < 65536)); 
    assert((inputStreamPtr != NULL) || (outputStreamPtr != NULL)); 

    readStream = NULL; 
    writeStream = NULL; 

    CFStreamCreatePairWithSocketToHost(
             NULL, 
             (CFStringRef) hostName, 
             port, 
             ((inputStreamPtr != NULL) ? &readStream : NULL), 
             ((outputStreamPtr != NULL) ? &writeStream : NULL) 
             ); 

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

    if (readStream) { 
     CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings); 
    } 

    if (writeStream) { 
     CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings); 
    } 

    if (inputStreamPtr != NULL) { 
     *inputStreamPtr = CFBridgingRelease(readStream); 
    } 
    if (outputStreamPtr != NULL) { 
     *outputStreamPtr = CFBridgingRelease(writeStream); 
    } 


} 

@end 

To wszystko nie można połączyć się z serwerem tak:

NSInputStream *inputStream; 
NSOutputStream *outputStream; 
[NSStream qNetworkAdditions_getStreamsToHostNamed:host 
              port:port 
             inputStream:&inputStream 
            outputStream:&outputStream]; 

     inputStream.delegate = self; 
     outputStream.delegate = self; 

gdzie "ja" jest zgodny z protokołem NSStreamDelegate.

Mam nadzieję, że te fragmenty będą pomocne.

+1

Oto link do docs Apple, do którego odnosi się Arndt: https://developer.apple.com/library/ios/qa/qa1652/_index.html – Fletch

Powiązane problemy