Iphone 始终在扇区上执行坏访问
我正在使用评估X509证书。 我已经修改了一点,以便从我的包中获取证书(只更改了文件名) 当我运行此命令时,它总是在注释5的行中崩溃,状态=SecTrustEvaluate(myTrust,&trustResult)代码>。我在那里得到一个总是Iphone 始终在扇区上执行坏访问,iphone,objective-c,validation,x509certificate,evaluation,Iphone,Objective C,Validation,X509certificate,Evaluation,我正在使用评估X509证书。 我已经修改了一点,以便从我的包中获取证书(只更改了文件名) 当我运行此命令时,它总是在注释5的行中崩溃,状态=SecTrustEvaluate(myTrust,&trustResult)。我在那里得到一个总是的EXC\u BAD\u访问权限 - (BOOL)validateCertificate { NSString *thePath = [[NSBundle mainBundle] pathForResource:@"user_signed_cert" o
的EXC\u BAD\u访问权限
- (BOOL)validateCertificate
{
NSString *thePath = [[NSBundle mainBundle] pathForResource:@"user_signed_cert" ofType:@"crt"];
NSData *certData = [[NSData alloc]
initWithContentsOfFile:thePath];
CFDataRef myCertData = (__bridge_retained CFDataRef)certData; //1
SecCertificateRef myCert;
myCert = SecCertificateCreateWithData(NULL, myCertData); //2
SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); //3
SecCertificateRef certArray[1] = { myCert };
CFArrayRef myCerts = CFArrayCreate(
NULL, (void *)certArray,
1, NULL);
SecTrustRef myTrust;
OSStatus status = SecTrustCreateWithCertificates(
myCerts,
myPolicy,
&myTrust); //4
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(myTrust, &trustResult); //5 }
NSLog(@"Status: %d", status);
//6 if (trustResult == kSecTrustResultRecoverableTrustFailure) {
}
if (myPolicy)
CFRelease(myPolicy);
}
有人知道这里出了什么问题吗
提前谢谢
更新#1:我已将其更改为以下内容,但没有任何更改。SecTrustEvaluate()
NSMutableArray *temp = [[NSMutableArray alloc] init];
[temp addObject:certData];
OSStatus status = SecTrustCreateWithCertificates((__bridge CFArrayRef)temp, myPolicy, &myTrust);
似乎status
在SecTrustCreateWithCertificates()之后为空,但不包含错误
还有其他建议吗?怎么了
更新#2:我尝试了下面提到的解决方案,并始终收到kSecTrustResultInvalid
。我仅将CA证书创建更改为将私钥存储在CA.key
中,因为在签署请求(client.csr
)时,我收到以下错误消息:
Signature ok
subject=/CN=foo-by-ZeeCA
Getting CA Private Key
unable to load CA Private Key
此外,我必须将签名请求命令更改为opensslx509-CA CA.pem-in client.csr-CAkey CA.key-req-set_serial 1-out client.pem
。(添加了-CAkey ca.key
)
然后,我使用了下面解决方案中的代码,并从包中添加了路径。此外,我还为状态添加了一个开关盒
/*
# CA
openssl req -x509 -new -subj /CN=ZeeCA -keyout ca.key -nodes -set_serial 1 > ca.pem
openssl x509 -outform DER -out ca.der -in ca.pem
# create andsign client
openssl req -new -subj /CN=foo-by-ZeeCA -CAkey ca.key -keyout client.key -nodes > client.csr
openssl x509 -CA ca.pem -in client.csr -req -set_serial 1 -out client.pem
# format for client identity import
openssl pkcs12 -export -out client.12 -inkey client.key -in client.pem -CAfile ca.pem -password pass:1234
# format for trust.
openssl x509 -in client.pem -out client.der -outform der
*/
NSString *clientPath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"der"];
//NSString *thePath = @"XXXX/client.der";
NSData *certData = [[NSData alloc]
initWithContentsOfFile:clientPath];
CFDataRef myCertData = (__bridge_retained CFDataRef)certData; //1
assert(myCertData);
SecCertificateRef myCert;
myCert = SecCertificateCreateWithData(NULL, myCertData); //2
assert(myCert);
SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); //3
NSArray * certArray = [NSArray arrayWithObject:(__bridge id)(myCert)];
SecTrustRef myTrust;
OSStatus status = SecTrustCreateWithCertificates(
(__bridge CFArrayRef)certArray,
myPolicy,
&myTrust); //4
NSString *caPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"der"];
NSData *caData = [[NSData alloc]
initWithContentsOfFile:caPath];
CFDataRef myCaData = (__bridge_retained CFDataRef)caData;
SecCertificateRef myCA = SecCertificateCreateWithData(NULL, myCaData);
assert(myCA);
NSArray * myCAs = [NSArray arrayWithObject:(__bridge id)(myCA)];
SecTrustResultType xxx = SecTrustSetAnchorCertificates(myTrust, (__bridge CFArrayRef)(myCAs));
if (xxx != noErr) {
NSLog(@"SecTrustSetAnchorCertificates failed: %d", xxx);
}
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(myTrust, &trustResult); //5 }
NSLog(@"Status: %d", status);
}
if (myPolicy)
CFRelease(myPolicy);
if (status == noErr) {
status = SecTrustEvaluate(myTrust, &trustResult); //5 }
switch (status) {
case kSecTrustResultProceed: // 1
NSLog(@"Proceed");
break;
case kSecTrustResultConfirm: // 2
NSLog(@"Confirm");
break;
case kSecTrustResultUnspecified: // 4
NSLog(@"Unspecified");
break;
case kSecTrustResultRecoverableTrustFailure: // 5
NSLog(@"TrustFailure");
break;
case kSecTrustResultDeny: // 3
NSLog(@"Deny");
break;
case kSecTrustResultFatalTrustFailure: // 6
NSLog(@"FatalTrustFailure");
break;
case kSecTrustResultOtherError: // 7
NSLog(@"OtherError");
break;
case kSecTrustResultInvalid: // 0
NSLog(@"Invalid");
break;
default:
NSLog(@"Default");
break;
}
}
我认为你的问题是一系列的。我使用下面的代码-即,在你称之为myCerts的地方传递一个简单的SecCertificateRef平面数组
NSMutableArray *serverChain = [NSMutableArray array];
for(int i = 0; i < SecTrustGetCertificateCount(secTrustRef); i++)
[serverChain addObject:(__bridge id)(SecTrustGetCertificateAtIndex(secTrustRef,i))];
SecTrustRef noHostTrustRef = NULL;
OSErr status = SecTrustCreateWithCertificates((__bridge CFArrayRef) serverChain, SecPolicyCreateSSL(NO, nil), &noHostTrustRef);
if (status != noErr) {
NSLog(@"SecTrustCreateWithCertificates failed: %hd", status);
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
NSMutableArray *certRefs = [NSMutableArray arrayWithCapacity:[acceptableCAs count]];
for(Certificate * cert in acceptableCAs)
[certRefs addObject:(id)[cert secCertificateRef]];
status = SecTrustSetAnchorCertificates(noHostTrustRef, (__bridge CFArrayRef)certRefs);
if (status != noErr) {
NSLog(@"SecTrustSetAnchorCertificates failed: %hd", status);
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
status = SecTrustEvaluate(noHostTrustRef, &result);
if (status != noErr) {
NSLog(@"SecTrustEvaluate failed: %hd", status);
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
CFRelease(noHostTrustRef);
并且有明确的证书:
@autoreleasepool {
/*
# CA
openssl req -x509 -new -subj /CN=ZeeCA -keyout /dev/stdout -nodes -set_serial 1 > ca.pem
openssl x509 -outform DER -out ca.der -in ca.pem
# create andsign client
openssl req -new -subj /CN=foo-by-ZeeCA -keyout client.key -nodes > client.csr
openssl x509 -CA ca.pem -in client.csr -req -set_serial 1 -out client.pem
# format for client identity import
openssl pkcs12 -export -out client.12 -inkey client.key -in client.pem -CAfile ca.pem -password pass:1234
# format for trust.
openssl x509 -in client.pem -out client.der -outform der
*/
NSString *thePath = @"XXXX/client.der";
NSData *certData = [[NSData alloc]
initWithContentsOfFile:thePath];
CFDataRef myCertData = (__bridge_retained CFDataRef)certData; //1
assert(myCertData);
SecCertificateRef myCert;
myCert = SecCertificateCreateWithData(NULL, myCertData); //2
assert(myCert);
SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); //3
NSArray * certArray = [NSArray arrayWithObject:(__bridge id)(myCert)];
SecTrustRef myTrust;
OSStatus status = SecTrustCreateWithCertificates(
(__bridge CFArrayRef)certArray,
myPolicy,
&myTrust); //4
NSData *caData = [[NSData alloc]
initWithContentsOfFile:@"XXXXX/ca.der"];
CFDataRef myCaData = (__bridge_retained CFDataRef)caData;
SecCertificateRef myCA = SecCertificateCreateWithData(NULL, myCaData);
assert(myCA);
NSArray * myCAs = [NSArray arrayWithObject:(__bridge id)(myCA)];
SecTrustResultType xxx = SecTrustSetAnchorCertificates(myTrust, (__bridge CFArrayRef)(myCAs));
if (xxx != noErr) {
NSLog(@"SecTrustSetAnchorCertificates failed: %d", xxx);
}
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(myTrust, &trustResult); //5 }
NSLog(@"Status: %d", status);
//6 if (trustResult == kSecTrustResultRecoverableTrustFailure) {
}
if (myPolicy)
CFRelease(myPolicy);
}
两者似乎都能帮我解决问题?更新了答案-我想知道您的文件是否满意和/或格式是否正确。包括一些openssl来排除这种情况。谢谢,它可以工作!似乎我的证书创建是错误的。(openssl x509-CA CA.pem-in user.csr-req-set_serial 1-outform DER-out user.DER-CAkey CA.key
)此外,当我检查结果(status
)时,它告诉我证书无效。基本上,当我将CA证书导入我的设备(例如通过电子邮件)并确认其可信时,评估应该成功吗?我这么问是因为我已经试过了,但结果仍然无效?!对的据我所知,iPhone需要根据as DER进行验证的证书,以及用于客户端身份验证的证书,如P12。如果您想根据用于客户端身份验证的同一证书进行验证,那么我发现我需要将其作为DER(当然是无私钥)单独导入,以便同时使用它进行信任。这意味着当我将用户证书(user\u signed\u cert.DER
)及其密钥(user\u key.key
)打包到pkcs12容器中时(使用openssl pkcs12…
)然后我可以像前面提到的那样导入它(只需将path
设置为.p12文件),它应该可以工作了?我明天就要尝试了!谢谢!
@autoreleasepool {
/*
# CA
openssl req -x509 -new -subj /CN=ZeeCA -keyout /dev/stdout -nodes -set_serial 1 > ca.pem
openssl x509 -outform DER -out ca.der -in ca.pem
# create andsign client
openssl req -new -subj /CN=foo-by-ZeeCA -keyout client.key -nodes > client.csr
openssl x509 -CA ca.pem -in client.csr -req -set_serial 1 -out client.pem
# format for client identity import
openssl pkcs12 -export -out client.12 -inkey client.key -in client.pem -CAfile ca.pem -password pass:1234
# format for trust.
openssl x509 -in client.pem -out client.der -outform der
*/
NSString *thePath = @"XXXX/client.der";
NSData *certData = [[NSData alloc]
initWithContentsOfFile:thePath];
CFDataRef myCertData = (__bridge_retained CFDataRef)certData; //1
assert(myCertData);
SecCertificateRef myCert;
myCert = SecCertificateCreateWithData(NULL, myCertData); //2
assert(myCert);
SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); //3
NSArray * certArray = [NSArray arrayWithObject:(__bridge id)(myCert)];
SecTrustRef myTrust;
OSStatus status = SecTrustCreateWithCertificates(
(__bridge CFArrayRef)certArray,
myPolicy,
&myTrust); //4
NSData *caData = [[NSData alloc]
initWithContentsOfFile:@"XXXXX/ca.der"];
CFDataRef myCaData = (__bridge_retained CFDataRef)caData;
SecCertificateRef myCA = SecCertificateCreateWithData(NULL, myCaData);
assert(myCA);
NSArray * myCAs = [NSArray arrayWithObject:(__bridge id)(myCA)];
SecTrustResultType xxx = SecTrustSetAnchorCertificates(myTrust, (__bridge CFArrayRef)(myCAs));
if (xxx != noErr) {
NSLog(@"SecTrustSetAnchorCertificates failed: %d", xxx);
}
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(myTrust, &trustResult); //5 }
NSLog(@"Status: %d", status);
//6 if (trustResult == kSecTrustResultRecoverableTrustFailure) {
}
if (myPolicy)
CFRelease(myPolicy);
}