2012-04-20 4 views
6

내 앱이 연결하려는 서버로부터 인증 요청을 받고 있으므로 connection:didReceiveAuthenticationChallenge: 메서드를 구현했습니다. SecCertificateRefSecIdentityRef을 보내야합니다. ID가 작동하지만 인증서를 NSArray으로 보내야하고 CFArrayRefNSArray으로 변환하는 방법을 알 수 없습니다.NSURLConnection 인증 문제에 대한 SecCertificateRef 만들기

// 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; 
} 

그리고 다음 connection:didReceiveAuthenticationChallenge:에서 내가 가진 :

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

응용 프로그램 충돌합니다 NSURLCredential가 만들어

이것은 정체성과 인증서를 만들기위한 나의 방법이다. 추가 검사를 통해 CFArrayRefNSArray으로 변환하면 SecCertificateRef의 데이터가 손실되고 배열에 오류가 발생하여 null이 포함되어 있다고 결론을 냈습니다.

NSArraySecCertificateRef을 어떻게 배치 할 수 있습니까? 나는 한 걸음도 놓쳤는가? 아니면 그냥 잘못하고있는 것인가?

답변

6

마침내 대답을 찾았습니다. 내 인증서를 만들려면 SecCertificateCreateWithData(nil, inPKCS12Data); 대신 SecIdentityCopyCertificate(identity, &certificateRef);을 사용해야했습니다.