kCFStreamPropertySocketSecurityLevel 到 kCFStreamSocketSecurityLevelNegotiatedSSL 导致 OSStatus errSSLXCertChainInvalid (-9807) 连接到 Java
我有一个简单的 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();
}
我使用在 iphone 模拟器中运行的简单 ios 客户端连接到它:
- (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;
}
}
Why does set kCFStreamPropertySocketSecurityLevel to kCFStreamSocketSecurityLevelNegotiedSSL 导致我的 SSL 握手失败?
I have a simple Java server that uses a self-signed cert to identify itself that I created with 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();
}
I connect to it with a simple ios client running in the iphone simulator:
- (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;
}
}
Why does setting kCFStreamPropertySocketSecurityLevel to kCFStreamSocketSecurityLevelNegotiatedSSL cause my SSL handshake to fail?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
答案来自 cocoa-unbound。我需要首先设置 kCFStreamPropertySocketSecurityLevel,因为设置它会将我的 kCFStreamPropertySSLSettings 恢复为默认值。当然,文档提到没有这个。
The answer is from cocoa-unbound. I need to set kCFStreamPropertySocketSecurityLevel first because setting it reverts my kCFStreamPropertySSLSettings to defaults. Of course, the documentation mentions nothing of this.
OSStatus -9807 是:
您的客户端无法验证自签名证书的有效性。
OSStatus -9807 is:
Your client is unable to verify the validity of the self-signed certificate.