*解决了*
我的问题是引用以下问题:
Objective-C: How to verify SecCertificateRef with signer's public key?
我们有自己的公钥基础设施,所以我们信任自己的rootCA。使用此rootCA,我们对交付给个人服务器的证书进行签名。现在,我想连接到iOS应用程序,并检查从服务器交付的证书是否与我们的CA签名。
我的应用程序应该能够使用由建立的TCP连接连接到n台服务器,(也许可以使用零conf服务)连接到n台服务器。我有我的应用程序的公共部分的证书,我想添加到我的"CertChain“,以便应用程序将信任他们的连接。
我已经试过很多次了,但是我仍然无法通过SecTrustEvaluate(trust, &result);并取得一个有效的结果。(我想在生产性中使用它,所以请不要告诉我任何关于失效验证的事情)
我的证书:
在app中: rootCA,oldServerCA (cer)
服务器上(通过信任):homeServer,oldServer
我的证书链:
rootCA签名homeServer
oldServerCA签名oldServer
我的代码部分:
添加更新
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port;
{
// Configure SSL/TLS settings
NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:3];
// Allow self-signed certificates
[settings setObject:[NSNumber numberWithBool:YES]
forKey:GCDAsyncSocketManuallyEvaluateTrust];
[sock startTLS:settings];
// get the certificates as data for further operations
NSString *certFilePath1 = [[NSBundle mainBundle] pathForResource:@"rootCA" ofType:@"cer"]; // also tried it with 'der', same result
NSData *certData1 = [NSData dataWithContentsOfFile:certFilePath1];
NSString *certFilePath2 = [[NSBundle mainBundle] pathForResource:@"oldServerCA" ofType:@"cer"];
NSData *certData2 = [NSData dataWithContentsOfFile:certFilePath2];
// if data exists, use it
if(certData1 && certData2)
{
SecCertificateRef cert1;
cert1 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData1);
SecCertificateRef cert2;
cert2 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData2);
// only working for "cer"
NSString *name = [NSString stringWithUTF8String:CFStringGetCStringPtr(SecCertificateCopySubjectSummary(cert1), kCFStringEncodingUTF8)];
// maybe I understood the usage of "name" in "kSecAttrApplicationTag" wrong?
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)(kSecClassKey), kSecClass,
(__bridge id)kSecAttrKeyTypeRSA, kSecAttrKeyType,
(__bridge id)kSecAttrKeyClassPublic, kSecAttrKeyClass,
kCFBooleanTrue, kSecAttrIsPermanent,
[name dataUsingEncoding:NSUTF8StringEncoding], kSecAttrApplicationTag,
certData1, kSecValueData,
kCFBooleanTrue, kSecReturnPersistentRef,
nil],
NULL); //don't need public key ref
// Setting "cer" is successfully and delivers "noErr" in first run, then "errKCDuplicateItem"
NSLog(@"evaluate with status %d", (int)status);
NSString *name2 = [NSString stringWithUTF8String:CFStringGetCStringPtr(SecCertificateCopySubjectSummary(cert2), kCFStringEncodingUTF8)];
OSStatus status2 = SecItemAdd((__bridge CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)(kSecClassKey), kSecClass,
(__bridge id)kSecAttrKeyTypeRSA, kSecAttrKeyType,
(__bridge id)kSecAttrKeyClassPublic, kSecAttrKeyClass,
kCFBooleanTrue, kSecAttrIsPermanent,
[name2 dataUsingEncoding:NSUTF8StringEncoding], kSecAttrApplicationTag,
certData2, kSecValueData,
kCFBooleanTrue, kSecReturnPersistentRef,
nil],
NULL); //don't need public key ref
NSLog(@"evaluate with status %d", (int)status2);
// log here -> certificates were loaded. Fine
// create references of each to proof them seperatly
const void *ref[] = {cert1};
CFArrayRef aryRef = CFArrayCreate(NULL, ref, 1, NULL);
const void *ref2[] = {cert2};
CFArrayRef aryRef2 = CFArrayCreate(NULL, ref2, 1, NULL);
// need this way to get sock.sslContext, otherways it's NULL (see implementation of GCDAsyncSocket)
[sock performBlock:^{
SSLContextRef sslContext = sock.sslContext;
OSStatus status = SSLSetCertificate(sslContext, aryRef);
// the status is everywhere always -909 -> badReqErr /*bad parameter or invalid state for operation*/
if(status == noErr)
NSLog(@"successfully set ssl certificates");
else
NSLog(@"setting ssl certificates failed");
status = SSLSetCertificate(sock.sslContext, aryRef2);
if(status == noErr)
NSLog(@"successfully set ssl certificates");
else
NSLog(@"setting ssl certificates failed");
status = SSLSetEncryptionCertificate(sock.sslContext, aryRef);
if(status == noErr)
NSLog(@"successfully set ssl certificates");
else
NSLog(@"setting ssl certificates failed");
}];
}
@synchronized( self )
{
if( isConnected == NO )
{
if(gcdAsyncSocket && [gcdAsyncSocket isConnected])
{
isConnected = YES;
[gcdAsyncSocket readDataWithTimeout:READ_TIMEOUT tag:0];
[NSThread detachNewThreadSelector:@selector(readDataToData:withTimeout:tag:) toTarget:gcdAsyncSocket withObject:nil];
[gcdAsyncSocket readDataToData:[GCDAsyncSocket LFData] withTimeout:READ_TIMEOUT tag:0];
[del onConnect];
}
}
}
}好吧..。如果不在这里工作,那就手动检查.
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
{
// https://code.csdn.net/OS_Mirror/CocoaAsyncSocket/file_diff/a4b9c4981b3c022ca89d0cdaadecc70b825ad4f1...5d58af30d2d8a3e0f7219487e72f1b4b2c3b4894/GCD/Xcode/SimpleHTTPClient/Desktop/SimpleHTTPClient/SimpleHTTPClientAppDelegate.m
dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(bgQueue, ^{
// This is where you would (eventually) invoke SecTrustEvaluate.
// Presumably, if you're using manual trust evaluation, you're likely doing extra stuff here.
// For example, allowing a specific self-signed certificate that is known to the app.
NSString *certFilePath1 = [[NSBundle mainBundle] pathForResource:@"rootCA" ofType:@"cer"];
NSData *certData1 = [NSData dataWithContentsOfFile:certFilePath1];
NSString *certFilePath2 = [[NSBundle mainBundle] pathForResource:@"oldServerCA" ofType:@"cer"];
NSData *certData2 = [NSData dataWithContentsOfFile:certFilePath2];
if(certData1 && certData2)
{
CFArrayRef arrayRefTrust = SecTrustCopyProperties(trust);
SecTrustResultType result = kSecTrustResultUnspecified;
// usualy should work already here
OSStatus status = SecTrustEvaluate(trust, &result);
NSLog(@"evaluate with result %d and status %d", result, (int)status);
NSLog(@"trust properties: %@", arrayRefTrust);
/* log:
evaluate with result 5 and status 0
trust properties: (
{
type = error;
value = "Root certificate is not trusted."; // expected, when top part was not working
}
*/
SecCertificateRef cert1;
cert1 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData1);
SecCertificateRef cert2;
cert2 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData2);
const void *ref[] = {cert1};
CFIndex count = SecTrustGetCertificateCount(trust);
// CFMutableArrayRef aryRef = CFArrayCreateMutable(NULL, count + 1, NULL);
// CFArrayAppendValue(aryRef, ref);
CFArrayCreate(NULL, ref, 2, NULL);
// # # # #
// so check one by one...
BOOL isMatching = NO;
for (int i = 0; i < count; i++)
{
SecCertificateRef certRef = SecTrustGetCertificateAtIndex(trust, i);
NSString *name = [NSString stringWithUTF8String:CFStringGetCStringPtr(SecCertificateCopySubjectSummary(certRef), kCFStringEncodingUTF8)]; // only working for "cer"
NSLog(@"remote cert at index %d is '%@'", i, name);
/*
first is 'homeserver', second is 'oldServer'
*/
// const void *ref[] = {certRef, cert1, cert2};
// CFArrayRef aryCheck = CFArrayCreate(NULL, ref, 3, NULL);
// check against the new cert (rootCA)
const void *ref[] = {certRef, cert1};
CFArrayRef aryCheck = CFArrayCreate(NULL, ref, 2, NULL);
SecTrustRef trustManual;
OSStatus certStatus = SecTrustCreateWithCertificates(aryCheck, SecPolicyCreateBasicX509(), &trustManual);
// certStatus always noErr
NSLog(@"certStatus: %d", (int)certStatus);
SecTrustResultType result;
OSStatus status = SecTrustEvaluate(trustManual, &result);
CFArrayRef arrayRef = SecTrustCopyProperties(trustManual);
NSLog(@"evaluate with result %d and status %d", result, (int)status);
NSLog(@"trust properties: %@", arrayRef);
/* log:
evaluate with result 5 and status 0
trust properties: (
{
type = error;
value = "Root certificate is not trusted.";
}
*/
// always else-part because result is "kSecTrustResultRecoverableTrustFailure"
if (status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified))
{
isMatching = YES;
NSLog(@"certificates matches");
}
else
{
NSLog(@"certificates differs");
}
}
if (isMatching || (status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)))
{
completionHandler(YES);
}
else
{
completionHandler(NO);
}
}
completionHandler(NO);
});
}更新1
删除
[settings setObject:[NSNumber numberWithBool:YES]
forKey:GCDAsyncSocketManuallyEvaluateTrust];现在使用
SecCertificateRef cert1, cert2;
// init certs, see top part
// according to @SeanBaker "Certs[0] would be nil (you don't want to do client auth), and certs[1...] would be the root certificates you want to trust in establishing the connection"
const void *certs[] = {NULL, cert1, cert2};
// const void *certs[] = {nil, cert1, cert2};
CFArrayRef aryCerts = CFArrayCreate(NULL, certs, 3, NULL);
[settings setObject:(__bridge NSArray*)aryCerts
forKey:(NSString *)kCFStreamSSLCertificates];但是让OSStatus -50 (/*error in user parameter list*/)在
// 2. kCFStreamSSLCertificates
value = [tlsSettings objectForKey:(NSString *)kCFStreamSSLCertificates];
if ([value isKindOfClass:[NSArray class]])
{
CFArrayRef certs = (__bridge CFArrayRef)value;
status = SSLSetCertificate(sslContext, certs);
...似乎我使用它是错误的,但我没有看到错误:/ (不经常使用核心基础)
如果你需要更多的信息,就问吧。每一个提示都能拯救生命:)
发布于 2015-02-18 10:41:29
通过在手动检查anchorCertificates中将证书设置为信任的- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler来解决这个问题,但是感谢您的提示和努力:)将为此给您一些好处。
NSString *certFilePath1 = [[NSBundle mainBundle] pathForResource:@"rootCA" ofType:@"cer"];
NSData *certData1 = [NSData dataWithContentsOfFile:certFilePath1];
NSString *certFilePath2 = [[NSBundle mainBundle] pathForResource:@"oldServerCA" ofType:@"cer"];
NSData *certData2 = [NSData dataWithContentsOfFile:certFilePath2];
OSStatus status = -1;
SecTrustResultType result = kSecTrustResultDeny;
if(certData1 && certData2)
{
SecCertificateRef cert1;
cert1 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData1);
SecCertificateRef cert2;
cert2 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData2);
const void *ref[] = {cert1, cert2};
CFArrayRef ary = CFArrayCreate(NULL, ref, 2, NULL);
SecTrustSetAnchorCertificates(trust, ary);
status = SecTrustEvaluate(trust, &result);
}
else
{
NSLog(@"local certificates could not be loaded");
completionHandler(NO);
}
if ((status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)))
{
completionHandler(YES);
}
else
{
CFArrayRef arrayRefTrust = SecTrustCopyProperties(trust);
NSLog(@"error in connection occured\n%@", arrayRefTrust);
completionHandler(NO);
}发布于 2015-02-17 12:16:39
我自己使用自定义证书来验证我们的消息应用程序在开发模式下使用的多个服务器。
如果您可以访问p12(包括私钥和签名标识)文件,则可以使用kCFStreamSSLCertificates验证服务器证书。
否则(在只有公钥的情况下),您可以通过对等名kCFStreamSSLPeerName进行验证。
在您的代码片段中,您正在做的一件不正确的事情是如何向GCDAsyncSocket模块提供证书。从而找出你提到的错误。
正确的方法如下:
NSArray *myCerts = [[NSArray alloc] initWithObjects:(__bridge id)identity1, (__bridge id)myReturnedCertificate1, nil];
[settings setObject:myCerts forKey:(NSString *)kCFStreamSSLCertificates];根据苹果的文档标识,在使用kCFStreamSSLCertificates时是强制性的:
您必须在certRefs中放置一个SecIdentityRef对象,该对象标识叶证书及其相应的私钥。指定根证书是可选的;
详细资料:
如果使用自定义签名的CA证书,下面是要遵循的步骤。请注意:示例基于GCDAsyncSocket
(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)主机端口:(Uint16_t)端口;
在此功能中向GCDAsyncSocket提供证书
NSArray *myCerts = [[NSArray alloc] initWithObjects:(__bridge id)identity1, (__bridge id)myReturnedCertificate1, nil];
[settings setObject:myCerts forKey:(NSString *)kCFStreamSSLCertificates];在下面使用“是”(不推荐)或“否”,根据需要手动验证信任?
[settings setObject:[NSNumber numberWithBool:YES]
forKey:GCDAsyncSocketManuallyEvaluateTrust];(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)信任completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
在此功能中,您应该读取信任中的所有证书,并尝试与应用程序提供的证书匹配。
样本代码:
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port;
{
// Configure SSL/TLS settings
NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:3];
// get the certificates as data for further operations
SecIdentityRef identity1 = nil;
SecTrustRef trust1 = nil;
NSData *certData1 = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"[Dev] InHouse_Certificates" ofType:@"p12"]];
CFDataRef myCertData1 = (__bridge_retained CFDataRef)(certData1);
[self extractIdentityAndTrust:myCertData1 withIdentity:&identity1 withTrust:&trust1 withPassword:CFSTR("1234")];
NSString* summaryString1 = [self copySummaryString:&identity1];
SecIdentityRef identity2 = nil;
SecTrustRef trust2 = nil;
NSData *certData2 = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"[Dis] InHouse_Certificates" ofType:@"p12"]];
CFDataRef myCertData2 = (__bridge_retained CFDataRef)(certData2);
[self extractIdentityAndTrust:myCertData2 withIdentity:&identity2 withTrust:&trust2 withPassword:CFSTR("1234")];
NSString* summaryString2 = [self copySummaryString:&identity2];
// if data exists, use it
if(myCertData1 && myCertData2)
{
//Delete if already exist. Just temporary
SecItemDelete((__bridge CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)(kSecClassKey), kSecClass,
(__bridge id)kSecAttrKeyTypeRSA, kSecAttrKeyType,
(__bridge id)kSecAttrKeyClassPublic, kSecAttrKeyClass,
kCFBooleanTrue, kSecAttrIsPermanent,
[summaryString1 dataUsingEncoding:NSUTF8StringEncoding], kSecAttrApplicationTag,
certData1, kSecValueData,
kCFBooleanTrue, kSecReturnPersistentRef,
nil]);
OSStatus status1 = SecItemAdd((__bridge CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)(kSecClassKey), kSecClass,
(__bridge id)kSecAttrKeyTypeRSA, kSecAttrKeyType,
(__bridge id)kSecAttrKeyClassPublic, kSecAttrKeyClass,
kCFBooleanTrue, kSecAttrIsPermanent,
[summaryString1 dataUsingEncoding:NSUTF8StringEncoding], kSecAttrApplicationTag,
certData1, kSecValueData,
kCFBooleanTrue, kSecReturnPersistentRef,
nil],
NULL); //don't need public key ref
// Setting "cer" is successfully and delivers "noErr" in first run, then "errKCDuplicateItem"
NSLog(@"evaluate with status %d", (int)status1);
//Delete if already exist. Just temporary
SecItemDelete((__bridge CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)(kSecClassKey), kSecClass,
(__bridge id)kSecAttrKeyTypeRSA, kSecAttrKeyType,
(__bridge id)kSecAttrKeyClassPublic, kSecAttrKeyClass,
kCFBooleanTrue, kSecAttrIsPermanent,
[summaryString2 dataUsingEncoding:NSUTF8StringEncoding], kSecAttrApplicationTag,
certData2, kSecValueData,
kCFBooleanTrue, kSecReturnPersistentRef,
nil]);
//NSString *name2 = [NSString stringWithUTF8String:CFStringGetCStringPtr(SecCertificateCopySubjectSummary(cert2), kCFStringEncodingUTF8)];
OSStatus status2 = SecItemAdd((__bridge CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)(kSecClassKey), kSecClass,
(__bridge id)kSecAttrKeyTypeRSA, kSecAttrKeyType,
(__bridge id)kSecAttrKeyClassPublic, kSecAttrKeyClass,
kCFBooleanTrue, kSecAttrIsPermanent,
[summaryString2 dataUsingEncoding:NSUTF8StringEncoding], kSecAttrApplicationTag,
certData2, kSecValueData,
kCFBooleanTrue, kSecReturnPersistentRef,
nil],
NULL); //don't need public key ref
NSLog(@"evaluate with status %d", (int)status2);
SecCertificateRef myReturnedCertificate1 = NULL;
OSStatus status3 = SecIdentityCopyCertificate (identity1, &myReturnedCertificate1);
SecCertificateRef myReturnedCertificate2 = NULL;
OSStatus status4 = SecIdentityCopyCertificate (identity2, &myReturnedCertificate2);
NSArray *myCerts = [[NSArray alloc] initWithObjects:(__bridge id)identity1, (__bridge id)myReturnedCertificate1, nil];
[settings setObject:myCerts forKey:(NSString *)kCFStreamSSLCertificates];
// Allow self-signed certificates
[settings setObject:[NSNumber numberWithBool:YES]
forKey:GCDAsyncSocketManuallyEvaluateTrust];
[sock startTLS:settings];
}
}如果出于某种原因,您决定手动评估信任。
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
{
dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(bgQueue, ^{
// This is where you would (eventually) invoke SecTrustEvaluate.
SecIdentityRef identity1 = nil;
SecTrustRef trust1 = nil;
NSData *certData1 = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"[Dev] InHouse_Certificates" ofType:@"p12"]];
CFDataRef myCertData1 = (__bridge_retained CFDataRef)(certData1);
[self extractIdentityAndTrust:myCertData1 withIdentity:&identity1 withTrust:&trust1 withPassword:CFSTR("1234")];
SecIdentityRef identity2 = nil;
SecTrustRef trust2 = nil;
NSData *certData2 = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"[Dis] InHouse_Certificates" ofType:@"p12"]];
CFDataRef myCertData2 = (__bridge_retained CFDataRef)(certData2);
[self extractIdentityAndTrust:myCertData2 withIdentity:&identity2 withTrust:&trust2 withPassword:CFSTR("1234")];
if(myCertData1 && myCertData2)
{
CFArrayRef arrayRefTrust = SecTrustCopyProperties(trust);
SecTrustResultType result = kSecTrustResultUnspecified;
// usualy should work already here
OSStatus status = SecTrustEvaluate(trust, &result);
NSLog(@"evaluate with result %d and status %d", result, (int)status);
NSLog(@"trust properties: %@", arrayRefTrust);
/* log:
evaluate with result 5 and status 0
trust properties: (
{
type = error;
value = "Root certificate is not trusted."; // expected, when top part was not working
}
*/
SecCertificateRef myReturnedCertificate1 = NULL;
OSStatus status3 = SecIdentityCopyCertificate (identity1, &myReturnedCertificate1);
SecCertificateRef myReturnedCertificate2 = NULL;
OSStatus status4 = SecIdentityCopyCertificate (identity2, &myReturnedCertificate2);
const void *ref[] = {myReturnedCertificate1};
CFIndex count = SecTrustGetCertificateCount(trust);
// CFMutableArrayRef aryRef = CFArrayCreateMutable(NULL, count + 1, NULL);
// CFArrayAppendValue(aryRef, ref);
CFArrayCreate(NULL, ref, 2, NULL);
// # # # #
// so check one by one...
BOOL isMatching = NO;
for (int i = 0; i < count; i++)
{
SecCertificateRef certRef = SecTrustGetCertificateAtIndex(trust, i);
NSString *name = [NSString stringWithUTF8String:CFStringGetCStringPtr(SecCertificateCopySubjectSummary(certRef), kCFStringEncodingUTF8)];
NSLog(@"remote cert at index %d is '%@'", i, name);
const void *ref[] = {certRef, myReturnedCertificate1};
CFArrayRef aryCheck = CFArrayCreate(NULL, ref, 2, NULL);
SecTrustRef trustManual;
OSStatus certStatus = SecTrustCreateWithCertificates(aryCheck, SecPolicyCreateBasicX509(), &trustManual);
// certStatus always noErr
NSLog(@"certStatus: %d", (int)certStatus);
SecTrustResultType result;
OSStatus status = SecTrustEvaluate(trustManual, &result);
CFArrayRef arrayRef = SecTrustCopyProperties(trustManual);
NSLog(@"evaluate with result %d and status %d", result, (int)status);
NSLog(@"trust properties: %@", arrayRef);
/* log:
evaluate with result 5 and status 0
trust properties: (
{
type = error;
value = "Root certificate is not trusted.";
}
*/
if (status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified))
{
isMatching = YES;
NSLog(@"certificates matches");
}
else
{
NSLog(@"certificates differs");
}
}
if (isMatching || (status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)))
{
completionHandler(YES);
}
else
{
completionHandler(NO);
}
}
completionHandler(NO);
});
}更新:
根据苹果的文档:
您必须在certRefs中放置一个SecIdentityRef对象,该对象标识叶证书及其相应的私钥。指定根证书是可选的;
正如苹果建议的那样,如果您使用的是证书in.cer格式,则应该使用对等域名(完全限定的域名)匹配这两种证书。
可以使用此函数验证对等方证书中的公共名称字段。如果调用此函数,并且证书中的公共名称与您在peerName参数中指定的值不匹配,则握手失败并返回errSSLXCertChainInvalid。使用此函数是可选的。
发布于 2015-02-15 17:09:27
为什么要手动评估信任?您是否可以将CA证书设置为GCDAsyncSocket的唯一可信根,以便在SSL设置中进行计算,并让它为您进行验证?
在这样的模型中,您将(1)减少您自己的编码工作量和风险(2)只信任由您的私有CA签署的证书,而不是信任默认信任存储中的公共CA。
https://stackoverflow.com/questions/28407397
复制相似问题