我想通过一些额外的检查来验证我的ssl服务器证书。有时我会得到一个
kSecTrustResultRecoverableTrustFailure
而不是
kSecTrustResultProceed
或kSecTrustResultUnspecified
似乎会发生
SecTrustSetAnchorCertificatesOnly(trust,YES)
已设置且锚证书仅在内置锚证书这取决于用于评估信任的AppleX509TP政策。
我的问题是,如果链失败,我不想相信,但我想相信如果使用MD5。
有没有办法找出评估失败的原因?
另一种方法是从CSSM_ALGID_MD5
中提取SecCertificateRef
吗?
答案 0 :(得分:3)
这可能是服务器证书问题....
检查here,我解决了我的 kSecTrustResultRecoverableTrustFailure 问题,将subjectAltName = DNS:example.com
添加到openssl配置文件中,特别是在服务器密钥生成中...
如果您没有使用openssl来生成它,我很抱歉,但我可以帮助您..无论如何,如果您想使用openssl,here是一个很好的教程,可以生成这些密钥然后用你的签名拥有自己的根证书权限。
在本教程中,我刚将openssl服务器配置文件更改为:
[ server ] basicConstraints = critical,CA:FALSE keyUsage = digitalSignature, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth nsCertType = server subjectAltName = IP:10.0.1.5,DNS:office.totendev.com
希望它有所帮助!
<强>编辑:强>
我的服务器评估代码:
#pragma mark - SERVER Auth Helper
//Validate server certificate with challenge
+ (BOOL)validateServerWithChallenge:(NSURLAuthenticationChallenge *)challenge {
//Get server trust management object a set anchor objects to validate it
SecTrustSetAnchorCertificates([challenge.protectionSpace serverTrust], (__bridge CFArrayRef)[self allowedCAcertificates]);
//Set to server trust management object to JUST ALLOW those anchor objects assigned to it (ABOVE), and disable apple CA trusts
SecTrustSetAnchorCertificatesOnly([challenge.protectionSpace serverTrust], YES);
//Try to evalute it
SecTrustResultType evaluateResult = kSecTrustResultInvalid; //evaluate result
OSStatus sanityCheck = SecTrustEvaluate([challenge.protectionSpace serverTrust], &evaluateResult);
//Check for no evaluate error
if (sanityCheck == noErr) {
//Check for result
if ([[self class] validateTrustResult:evaluateResult]) { return YES ; }
}
//deny!
return NO ;
}
//Validate SecTrustResulType
+ (BOOL)validateTrustResult:(SecTrustResultType)result {
switch (result) {
case kSecTrustResultProceed: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultProceed"); return YES ; }
break;
case kSecTrustResultConfirm: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultConfirm"); return YES ; }
break;
case kSecTrustResultUnspecified: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultUnspecified"); return YES ; }
break;
case kSecTrustResultDeny: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultDeny"); return YES ; }
break;
case kSecTrustResultFatalTrustFailure: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultFatalTrustFailure"); return NO ; }
break;
case kSecTrustResultInvalid: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultInvalid"); return NO ; }
break;
case kSecTrustResultOtherError: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultOtherError"); return NO ; }
break;
case kSecTrustResultRecoverableTrustFailure: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultRecoverableTrustFailure"); return NO ; }
break;
default: { TDLog(kLogLevelHandshake,nil,@"unkown certificate evaluate result type! denying..."); return NO ; }
break;
}
}
希望现在有所帮助:)!
答案 1 :(得分:0)
有没有办法找出评估失败的原因?
在致电SecTrustCopyProperties()
之后致电SecTrustEvaluate()
:
SecTrustRef trust = ...;
SecTrustResultType trustResult = kSecTrustResultOtherError;
OSStatus status = SecTrustEvaluate(trust, &trustResult);
if (trustResult == kSecTrustResultRecoverableTrustFailure) {
NSArray * trustProperties = (__bridge_transfer id)
SecTrustCopyProperties(certTrust);
}
trustProperties
是词典的数组,在评估的证书链中每个证书一个词典。每个词典都有一个条目title
,其中包含证书的名称;如果证书未评估,则它还包含一个条目error
,其中包含错误。例如。如果问题是证书已过期,则error
的值为CSSMERR_TP_CERT_EXPIRED
。