为NSURLConnection身份验证挑战创建SecCertificateRef [英] Creating a SecCertificateRef for NSURLConnection Authentication Challenge
问题描述
我从我的应用尝试连接的服务器收到身份验证质询,因此我实现了连接:didReceiveAuthenticationChallenge:
方法。我需要发送 SecCertificateRef
和 SecIdentityRef
。身份正在运行,但证书需要以 NSArray
的形式发送,我无法弄清楚如何转换 CFArrayRef
到 NSArray
。
I am receiving an authentication challenge from a server my app is trying to connect to, so I have implemented the connection:didReceiveAuthenticationChallenge:
method. I need to send a SecCertificateRef
and a SecIdentityRef
. The identity is working, but the the certificate needs to be sent as a NSArray
, and I can't figure out how to convert a CFArrayRef
to a NSArray
.
这是我创建身份和证书的方法:
This is my method for creating the identity and certificate:
// 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;
}
然后在连接中: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
已创建。经过进一步检查,我得出结论,当我将 CFArrayRef
转换为 NSArray
时,<$ c的数据$ c> SecCertificateRef 丢失,数组包含null导致崩溃。
The application crashes when the NSURLCredential
is created. Upon further inspection, I have concluded that when I convert the CFArrayRef
to a NSArray
, the data of the SecCertificateRef
is lost, and the array contains null causing a crash.
我怎样才能放置 SecCertificateRef
在 NSArray
中?我错过了一步,还是我做错了?
How could I place a SecCertificateRef
in a NSArray
? Did I miss a step, or am I just doing it wrong?
推荐答案
我终于找到了答案。我应该使用 SecIdentityCopyCertificate(identity,& certificateRef);
而不是 SecCertificateCreateWithData(nil,inPKCS12Data);
to创建我的证书。
I finally found the answer. I was supposed to use SecIdentityCopyCertificate(identity, &certificateRef);
instead of SecCertificateCreateWithData(nil, inPKCS12Data);
to create my certificate.
这篇关于为NSURLConnection身份验证挑战创建SecCertificateRef的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!