始终在SecTrustEvaluate上使用EXC_BAD_ACCESS [英] Always EXC_BAD_ACCESS on SecTrustEvaluate

查看:112
本文介绍了始终在SecTrustEvaluate上使用EXC_BAD_ACCESS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Apple的示例代码用于评估X509证书。
我修改了一下来从我的软件包中获取证书(只更改了文件名)。

I am using Apple's example code for evaluating a X509 certificate. I have modified a bit to obtain a certificate from my bundle (only changed the file name).

当我运行它时,它总是在崩溃的行中崩溃评论5 status = SecTrustEvaluate(myTrust,& trustResult); 。我总是 EXC_BAD_ACCESS 那里。

When I run this it always crashes in the line with comment 5 status = SecTrustEvaluate(myTrust, &trustResult);. I get an always EXC_BAD_ACCESS there.

- (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);
}

有谁知道这里出了什么问题?

Does anyone know what is going wrong here?

提前致谢!

更新#1:我已将其更改为以下内容,但没有任何变化。 上的EXC_BAD_ACCESS相同SecTrustEvaluate()

Update #1: I have changed it to the following but nothing changes. Same EXC_BAD_ACCESS on SecTrustEvaluate().

NSMutableArray *temp = [[NSMutableArray alloc] init];
[temp addObject:certData];
OSStatus status = SecTrustCreateWithCertificates((__bridge CFArrayRef)temp, myPolicy, &myTrust);

似乎状态 SecTrustCreateWithCertificates()但不包含错误。

其他任何建议都错了吗?

Any other suggestions whats wrong?

更新#2:我已尝试过下面提到的解决方案并始终收到 kSecTrustResultInvalid 。我只更改了CA证书创建,以将私钥存储在 ca.key 中,因为签署请求时( client.csr )我收到以下错误消息:

Update #2: I have tried the solution mentioned below and receive always kSecTrustResultInvalid. I have only changed the CA certificate creation to store the private key in ca.key because when signing the request (client.csr) I got the following error message:

Signature ok
subject=/CN=foo-by-ZeeCA
Getting CA Private Key
unable to load CA Private Key

此外,我不得不将签名请求命令更改为 openssl x509 -CA ca.pem -in client.csr -CAkey ca.key -req -set_serial 1 -out client.pem 。 (已添加 -CAkey ca.key

Furthermore I had to change the signing request command to openssl x509 -CA ca.pem -in client.csr -CAkey ca.key -req -set_serial 1 -out client.pem. (added -CAkey ca.key)

然后我使用了下面解决方案中的代码并添加了我的路径从捆绑。此外,我已为状态添加了一个开关案例。

Then I have used the code in the solution below and added my paths from the bundle. Additionally, I have added a switch-case for the status.

/*
 # 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平面数组。

I think your issue is in the array of an array. I use the code below - i.e. pass a simple flat array of SecCertificateRef's in what you call myCerts.

        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);

如果我把你的代码放在一个简单的cmd行包装器中:

If I take your code and put it in a simple cmd line wrapper:

int main(int argc,const char * argv [])
{

int main(int argc, const char * argv[]) {

@autoreleasepool {

    //  openssl req -x509 -new -subj /CN=foo -out user_signed_cert.crt \
    //      -keyout /dev/null -outform DER -nodes -set_serial 1
    //
    NSString *thePath = @"XXXXX/user_signed_cert.crt";

    NSData *certData = [[NSData alloc]
                        initWithContentsOfFile:thePath];
    CFDataRef myCertData = (__bridge_retained CFDataRef)certData; //1

    assert(myCertData);

    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);

}
return 0;

并带有明确的证书:

@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);

}

这两件事似乎对我有用吗?

both seem to do the trick for me ?

这篇关于始终在SecTrustEvaluate上使用EXC_BAD_ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆