シンプルな TCP サーバー/クライアントのセットアップがあります。この接続は実際にうまく機能します。
ここで、ソケット接続に SSL / TLS 暗号化を実装したいと考えました。キーチェーン アクセスを使用して PKCS12 証明書を作成しました。私のサーバーでは、受け入れコールバック内に次のコードがあります。
NSString *certificatePath = [[NSBundle mainBundle] pathForResource:@"TCPServerCertificate" ofType:@"p12"];
NSData *certificateData = [NSData dataWithContentsOfFile:certificatePath];
CFArrayRef keyRef;
OSStatus status = SecPKCS12Import((__bridge CFDataRef)certificateData, (__bridge CFDictionaryRef)@{(__bridge NSString *)kSecImportExportPassphrase: @"1234"}, &keyRef);
if (status != noErr) {
NSLog(@"PKCS12 import error %i", status);
return;
}
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(keyRef, 0);
SecIdentityRef identityRef = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
SecCertificateRef certificate;
status = SecIdentityCopyCertificate(identityRef, &certificate);
if (status != noErr) {
NSLog(@"sec identity copy failed: %i", status);
return;
}
NSArray *certificates = [NSArray arrayWithObjects:(__bridge id)identityRef, (__bridge id)certificate, nil];
NSDictionary *settings = @{(NSString *)kCFStreamPropertyShouldCloseNativeSocket: [NSNumber numberWithBool:YES],
(NSString *)kCFStreamSSLValidatesCertificateChain: [NSNumber numberWithBool:YES],
(NSString *)kCFStreamSSLAllowsExpiredCertificates: [NSNumber numberWithBool:NO],
(NSString *)kCFStreamSSLAllowsExpiredRoots: [NSNumber numberWithBool:NO],
(NSString *)kCFStreamSSLAllowsAnyRoot: [NSNumber numberWithBool:YES],
(NSString *)kCFStreamSSLCertificates: certificates,
(NSString *)kCFStreamSSLIsServer: [NSNumber numberWithBool:YES],
(NSString *)kCFStreamSSLLevel: (NSString *)kCFStreamSocketSecurityLevelTLSv1};
CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
次にNSStream
、ストリームのインスタンスを作成し、それらを別のクラスで処理します。
サーバーを実行してクライアントに接続するとNSStreamEventOpenCompleted
、デリゲートで定期的に取得されます。接続を閉じるだけでストリームまたはイベントに書き込もうとすると、次のエラーが発生します。
2013-10-25 13:27:08.584 TCPServer[6435:303] CFNetwork SSLHandshake failed (-9800)
2013-10-25 13:27:08.584 TCPServer[6435:303] NSStreamEventOpenCompleted
2013-10-25 13:27:08.585 TCPServer[6435:303] NSStreamEventErrorOccurred
クライアント側で何を実装しなければならないのだろうか。また、データを送信したり、クライアント側から切断したりするときにハンドシェイクが失敗するのはなぜだろうか。このエラーが発生するたびに、クライアントはまだ接続されていると見なします。
クライアント側とサーバー側の両方をカバーする優れた TCP SSL/TLS チュートリアルやその他の資料はありますか?