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ố SecCertificateRef
và SecIdentityRef
. 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?