kCFStreamPropertySocketSecurityLevel a kCFStreamSocketSecurityLevelNegotiatedSSL provoca OSStatus errSSLXCertChainInvalid (-9807) che collega a Java

StackOverflow https://stackoverflow.com/questions/4755499

Domanda

Ho un semplice server Java che utilizza un CERT auto-firmato per identificare se stesso che ho creato con 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();

  }

mi collego ad esso con il cliente un semplice ios in esecuzione nel simulatore 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;
 }
    }

Perché l'impostazione kCFStreamPropertySocketSecurityLevel al kCFStreamSocketSecurityLevelNegotiatedSSL causa mia handshake SSL a fallire?

È stato utile?

Soluzione

La risposta è da cacao non legato . Ho bisogno di impostare kCFStreamPropertySocketSecurityLevel in primo luogo perché l'impostazione viene ripristinata miei kCFStreamPropertySSLSettings ai valori predefiniti. Naturalmente, la documentazione menziona niente di tutto questo.

Altri suggerimenti

OSStatus -9807 è :

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

Il suo cliente è in grado di verificare la validità del certificato auto-firmato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top