2011-01-21 35 views
1

我有一個使用自簽名的證書證明自己的身份,我和密鑰工具創建了一個簡單的Java服務器:kCFStreamPropertySocketSecurityLevel到kCFStreamSocketSecurityLevelNegotiatedSSL導致OSStatus errSSLXCertChainInvalid(-9807)連接到Java

System.setProperty("javax.net.ssl.keyStore", "../../pki/z-keystore.jks"); 
    System.setProperty("javax.net.ssl.keyStorePassword", "ZZZZZZ"); 
    System.setProperty("javax.net.debug", "all"); 

    ServerSocketFactory serverSocketFactory = SSLServerSocketFactory 
    .getDefault(); 
    ServerSocket serverSocket = serverSocketFactory 
    .createServerSocket(8443); 

    System.out.println("Waiting for connections on 8443"); 
    final AtomicInteger nextSocketId = new AtomicInteger(); 
    while (true) { 
    final Socket socket = serverSocket.accept(); 
    new Thread(new Runnable() { 
    @Override 
    public void run() { 
    final int socketId = nextSocketId.getAndIncrement(); 

    try { 
     System.out.println("Received connection from socketId: " + socketId); 
     BufferedReader bufferedReader = new BufferedReader(
     new InputStreamReader(socket.getInputStream())); 
     PrintWriter printWriter = new PrintWriter(
     new OutputStreamWriter(socket.getOutputStream())); 

     for (String line = bufferedReader.readLine(); line != null; line = bufferedReader 
     .readLine()) { 
     System.out.println("Read: " + line); 
     printWriter.println("Read: " + line); 
     } 

     bufferedReader.close(); 
     printWriter.close(); 
    } catch (SSLHandshakeException e) { 
     // don't care 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    System.out.println("Closed connection from socketId: " + socketId); 
    } 
    }).start(); 

    } 

我連接到它與一個簡單的ios客戶端在iPhone模擬器運行:

- (void) connectSecurely { 
CFReadStreamRef readStream; 
CFWriteStreamRef writeStream; 
CFStreamCreatePairWithSocketToHost(NULL, 
      (CFStringRef)@"mcheath.local", 
      8443, 
      &readStream, 
      &writeStream); 

NSDictionary *sslSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
     (id)kCFBooleanFalse, (id)kCFStreamSSLValidatesCertificateChain, 
     nil]; 

CFReadStreamSetProperty(readStream, 
     kCFStreamPropertySSLSettings, 
     sslSettings); 

/* Turning on this setting makes the SSL handshake fail with OSStatus -9807 */ 
CFReadStreamSetProperty(readStream, 
     kCFStreamPropertySocketSecurityLevel, 
     kCFStreamSocketSecurityLevelNegotiatedSSL); 

self.inputStream = (NSInputStream *)readStream; 
self.outputStream = (NSOutputStream *)writeStream; 
[self.inputStream setDelegate:self]; 
[self.outputStream setDelegate:self]; 

[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] 
     forMode:NSDefaultRunLoopMode]; 
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] 
     forMode:NSDefaultRunLoopMode]; 

CFReadStreamOpen(readStream); 
CFWriteStreamOpen(writeStream); 
    } 

    #pragma mark - 
    #pragma mark NSStreamDelegate 

    - (void)stream:(NSStream *)aStream 
     handleEvent:(NSStreamEvent)eventCode { 
switch (eventCode) { 
    case NSStreamEventNone: 
    NSLog(@"NSStreamEventNone"); 
    break; 
    case NSStreamEventOpenCompleted: 
    NSLog(@"NSStreamEventOpenCompleted"); 
    break; 
    case NSStreamEventHasBytesAvailable: 
    NSLog(@"NSStreamEventHasBytesAvailable"); 
    break; 
    case NSStreamEventHasSpaceAvailable: 
    NSLog(@"NSStreamEventHasSpaceAvailable"); 
    break; 
    case NSStreamEventErrorOccurred: 
    NSLog(@"NSStreamEventErrorOccurred: %@", [aStream streamError]); 
    NSLog(@"SSL Settings: %@", [aStream propertyForKey:(NSString *) kCFStreamPropertySSLSettings]); 
    break; 
    case NSStreamEventEndEncountered: 
    NSLog(@"NSStreamEventEndEncountered"); 
    break; 
    default: 
    break; 
} 
    } 

爲什麼設置kCFStreamPropertySocketSecurityLevel到kCFStreamSocketSecurityLevelNegotiatedSSL引起我的SSL握手失敗?

回答

8

答案來自cocoa-unbound。我需要首先設置kCFStreamPropertySocketSecurityLevel,因爲它將我的kCFStreamPropertySSLSettings恢復爲默認值。當然,documentation沒有提到這一點。

+0

今天節省了我的一天。完全。 :) – 2013-10-22 09:16:23

0

OSStatus -9807 is

errSSLXCertChainInvalid  = -9807, /* Invalid certificate chain */ 

您的客戶端無法驗證自簽名證書的有效性。

+0

它不應該試圖驗證我的證書。我將kCFStreamSSLValidatesCertificateChain設置爲kBooleanFalse。如果我離開kCFStreamPropertySocketSecurityLevel未設置,一切正常,kCFStreamPropertySocketSecurityLevel設置爲kCFStreamSocketSecurityLevelTLSv1SSLv3。如果我將kCFStreamPropertySocketSecurityLevel設置爲kCFStreamSocketSecurityLevelTLSv1或kCFStreamSocketSecurityLevelSSLv3,我會得到違規狀態。 – 2011-01-21 19:56:12