为NSURLConnection身份验证挑战创建SecCertificateRef [英] Creating a SecCertificateRef for NSURLConnection Authentication Challenge

查看:633
本文介绍了为NSURLConnection身份验证挑战创建SecCertificateRef的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从我的应用尝试连接的服务器收到身份验证质询,因此我实现了连接: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屋!

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