我有一个用Delphi编写的TCP服务器和Windows客户端。我试图将它们移植到Mac,但似乎无法正确配置SSL。 在Windows中,应用程序将方法设置为SSLv2,并分配自签名的openssl证书文件和密钥文件,程序提供密码。
在Mac上我试图使用AsyncSocket复制它,但总是遇到握手错误:
在Mac客户端上,我收到错误:
CFNetwork SSLHandshake failed (-9806)
The operation couldn’t be completed. (kCFStreamErrorDomainSSL error -9806.)
在Windows Server上,我收到错误:
Error accepting connection with SSL.
error:140EC0AF:SSL routines:SSL2_READ_INTERNAL:non sslv2 initial packet
我在Mac上用于TCP客户端的代码:
SecIdentityRef identityRef = NULL;
SecCertificateRef certificateRef = NULL;
SecTrustRef trustRef = NULL;
NSString *thePath = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"pfx"];
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;
CFStringRef password = CFSTR("test");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = errSecSuccess;
securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);
identityRef = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
trustRef = (SecTrustRef)tempTrust;
} else {
NSLog(@"Certificates failed with error code %d",(int)securityError);
return;
}
SecIdentityCopyCertificate(identityRef, &certificateRef);
NSArray *certificates = [[NSArray alloc] initWithObjects:(id)identityRef, (id)certificateRef, nil];
NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
(id)kCFStreamSocketSecurityLevelSSLv2, (id)kCFStreamSSLLevel,
(id)kCFBooleanFalse, (id)kCFStreamSSLAllowsExpiredCertificates,
(id)kCFBooleanFalse, (id)kCFStreamSSLAllowsExpiredRoots,
(id)kCFBooleanTrue, (id)kCFStreamSSLAllowsAnyRoot,
certificates, (id)kCFStreamSSLCertificates,
nil];
tcpClient = [[AsyncSocket alloc] initWithDelegate:self];
NSError *err = nil;
if (![tcpClient connectToHost:ip onPort:tcpPort error:&err]) {
DoLog(@"Faled to connect to TCP Server: %@", err);
} else {
[tcpClient startTLS:settings];
}
[certificates release];
[settings autorelease];
使用以下openssl命令生成sample.pfx文件:
x509 -outform der -in sample.crt -out sample.der
pkcs12 -export -out sample.pfx -inkey sample.key -in sample.crt