kCFStreamPropertySocketSecurityLevel к kCFStreamSocketSecurityLevelNegotiatedSSL вызывает OSStatus errSSLXCertChainInvalid (-9807), соединяющийся с Java - PullRequest
1 голос
/ 21 января 2011

У меня есть простой Java-сервер, который использует самозаверяющий сертификат для идентификации себя, который я создал с помощью keytool:

  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?

Ответы [ 2 ]

8 голосов
/ 25 января 2011

Ответ от без какао . Мне нужно сначала установить kCFStreamPropertySocketSecurityLevel, потому что его установка возвращает мои значения kCFStreamPropertySSLSettings по умолчанию. Конечно, документация ничего не упоминает об этом.

0 голосов
/ 21 января 2011

OSStatus -9807 равен :

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

Ваш клиент не может проверить действительность самозаверяющего сертификата.

...