2012-04-20 27 views
6

Tôi đang nhận được một thách thức xác thực từ một máy chủ mà ứng dụng của tôi đang cố gắng kết nối, vì vậy tôi đã triển khai phương thức connection:didReceiveAuthenticationChallenge:. Tôi cần gửi số SecCertificateRefSecIdentityRef. Danh tính đang hoạt động nhưng chứng chỉ cần được gửi dưới dạng NSArray và tôi không thể tìm ra cách chuyển đổi một số CFArrayRef thành NSArray.Tạo một SecCertificateRef cho NSURLConnection Authentication Challenge

Đây là phương pháp của tôi để tạo bản sắc và giấy chứng nhận:

// Returns an array containing the certificate 
- (CFArrayRef)getCertificate { 
    SecCertificateRef certificate = nil; 
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"CertificateName" ofType:@"p12"]; 
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; 
    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data; 
    certificate = SecCertificateCreateWithData(nil, inPKCS12Data); 
    SecCertificateRef certs[1] = { certificate }; 
    CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL); 

    SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); 
    SecTrustRef myTrust; 

    OSStatus status = SecTrustCreateWithCertificates(array, myPolicy, &myTrust); 
    if (status == noErr) { 
    NSLog(@"No Err creating certificate"); 
    } else { 
    NSLog(@"Possible Err Creating certificate"); 
    } 
    return array; 
} 

// Returns the identity 
- (SecIdentityRef)getClientCertificate { 
    SecIdentityRef identityApp = nil; 
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"CertificateName" ofType:@"p12"]; 
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; 
    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data; 
    CFStringRef password = CFSTR("password"); 
    const void *keys[] = { kSecImportExportPassphrase };//kSecImportExportPassphrase }; 
    const void *values[] = { password }; 
    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); 
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); 
    OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items); 
    CFRelease(options); 
    CFRelease(password); 
    if (securityError == errSecSuccess) { 
    NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items)); 
    CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0); 
    identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); 
    } else { 
    NSLog(@"Error opening Certificate."); 
    } 
    return identityApp; 
} 

Và sau đó trong connection:didReceiveAuthenticationChallenge: tôi có:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    if ([challenge previousFailureCount] == 0) { 
    SecIdentityRef identity = [self getClientCertificate]; // Go get a SecIdentityRef 
    CFArrayRef certs = [self getCertificate]; // Get an array of certificates 

    // Convert the CFArrayRef to a NSArray 
    NSArray *myArray = (__bridge NSArray *)certs; 

    // Create the NSURLCredential 
    NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:certs persistence:NSURLCredentialPersistenceNone]; 

    // Send 
    [challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge]; 
    } else { 
    // Failed 
    [[challenge sender] cancelAuthenticationChallenge:challenge]; 
    } 
} 

Các ứng dụng bị treo khi NSURLCredential được tạo ra. Sau khi kiểm tra thêm, tôi đã kết luận rằng khi tôi chuyển đổi số CFArrayRef thành số NSArray, dữ liệu của số SecCertificateRef bị mất và mảng chứa null gây ra sự cố.

Tôi làm cách nào để đặt số SecCertificateRef trong một NSArray? Tôi đã bỏ lỡ một bước, hay tôi chỉ làm sai?

Trả lời

6

Cuối cùng tôi đã tìm thấy câu trả lời. Tôi đã định sử dụng SecIdentityCopyCertificate(identity, &certificateRef); thay vì SecCertificateCreateWithData(nil, inPKCS12Data); để tạo chứng chỉ của mình.

Các vấn đề liên quan