NSStream SSL на используемом сокете - PullRequest
8 голосов
/ 10 февраля 2010

Я пишу приложение, которое использует функции SSL NSStream на iphone. Я знаю, что SSL работает, потому что я могу напрямую подключаться к серверам, используя SSL.
Я столкнулся с проблемой, когда протоколы, использующие starttls, требуют, чтобы я общался по сокету с незащищенным, отправил команду starttls и затем повторно использовал этот сокет для SSL. Насколько я знаю, nsstream-соединения не могут быть повторно использованы, и я не могу запустить SSL на них после того, как открыл соединение.

Я думал о создании своего собственного сокета, обмениваясь данными по нему вручную, а затем настраивая NSstream, используя существующий сокет, и таким образом запускаю SSL. Тем не менее, кажется, что общение в сокете помещает его в состояние, когда я не могу запустить SSL на нем. Любая попытка использовать сокет для nsstream приводит к ошибке.

Есть мысли?

1 Ответ

7 голосов
/ 06 июня 2011

Это правильный способ сделать это. хотя это (установка свойства после подключения через сокет) недокументировано, это код непосредственно из моего клиента Monal xmpp, и Apple никогда не доставляла мне никаких проблем в магазине приложений.

 NSInputStream *iStream;
NSOutputStream *oStream;


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


[iStream open];
    [oStream open];

Как только соединение было открыто, и вы получили NSStreamEventOpenCompleted, и команда startTLS была отправлена ​​на хост с клиента:

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);
...