2013-06-14 2 views
0

내 응용 프로그램에서 certficate를 기반으로 사용자를 인증해야합니다. 이것은 내가하는 방법입니다 1. 우선, 인증서를 샌드 박스로 내 보냅니다. 2. 그런 다음 인증서에서 SecIdentityRef를 추출하고 키 체인에 추가 한 다음 나중에 샌드 박스에서 인증서를 삭제합니다. 3. NSURL 연결의 인증 요청에이 ID를 실제로 전달할 때 의미있는 정보를 제공하지 않고 응용 프로그램이 충돌합니다.정보없이 NSURLCredential이 충돌 함 - 인증서 기반 인증

다음은 모든 관련 코드는 응용 프로그램이 한 번 충돌 내가 NSURLChallenge 보낸 사람이 자격 증명을 전달하는 인증 요청

if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) 
    { 
     fprintf(stderr, "identities:\n"); 
     fprintf(stderr, "certificates:\n"); 
     NSLog(@"NSURLAuthenticationMethodClientCertificate"); 

     SecIdentityRef identity; 
     identity = (__bridge SecIdentityRef)([self _dumpCredentialsOfSecClass:kSecClassIdentity printSelector:@selector(_printIdentity:attributes:)]); 
     SecCertificateRef certificate1 = NULL; 
     OSStatus *stat = SecIdentityCopyCertificate (identity, &certificate1); 
     //const void *certs[] = {certificate1}; 

     SecCertificateRef certArray[1] = { certificate1 }; 
     CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL); 
     CFRelease(certificate1); 
     NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity 
                   certificates:(__bridge NSArray *)myCerts 
                    persistence:NSURLCredentialPersistencePermanent]; 
     CFRelease(myCerts); 

//  CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL); 
//   
//  NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistenceNone]; 
     [challenge.sender useCredential:credential forAuthenticationChallenge:challenge]; 
} 

이 자격 증명을 전달

//Exporting the certificate into the app and extracting the identity from it 

- (void)importCertificateIntoKeychain:(NSString *)Password 
{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Certificates"]; 
    NSString *certFolderName = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"CertificatePath"] lastPathComponent]stringByDeletingPathExtension]; 
    NSString *path = [NSString stringWithFormat:@"%@/%@",dataPath,certFolderName]; 
    NSArray*array = [[NSFileManager defaultManager] 
        contentsOfDirectoryAtPath: 
        path 
        error:nil]; 
    NSString *thePath; 
    NSString *fileName; 
    for (int i=0;i<array.count;i++) { 
     if ([[array objectAtIndex:i]hasSuffix:@".pfx"]) { 
      fileName= [array objectAtIndex:i]; 
      thePath = [NSString stringWithFormat:@"%@/%@",path,fileName]; 
     } 
    } 

    SecIdentityRef identityApp = nil; 

    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; 
    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data; 
    NSString *pwd = Password; 
    CFStringRef password = (CFStringRef)CFBridgingRetain(pwd); 
    const void *keys[] = { 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); 
     SecCertificateRef certificate = NULL; 
     SecIdentityCopyCertificate (identityApp, &certificate); 

     OSStatus status = errSecSuccess; 

     CFTypeRef persistent_ref = NULL; 
     const void *keys[] = { kSecReturnPersistentRef, kSecValueRef }; 
     const void *values[] = { kCFBooleanTrue, identityApp }; 
     CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values, 
                  2, NULL, NULL); 
     status = SecItemAdd(dict, &persistent_ref); 
     NSLog(@"Status %ld",status); 

     if (dict) 
     CFRelease(dict); 
     [Utils deleteCertificateFromInboxFolder]; 
    } else { 
     NSLog(@"Error opening Certificate."); 
     [Utils displayAlertWithTitle:@"Wrong Password" andMessage:@"Error opening certificate"]; 
    } 
} 

을 니펫입니다. enter image description here

어떤 도움

이 크게 감사합니다!

답변

0

좋아, 나는 그것을 고쳐 놓은 것 같다.

identity = (SecIdentityRef)CFBridgingRetain([self _dumpCredentialsOfSecClass:kSecClassIdentity printSelector:@selector(_printIdentity:attributes:)]);

희망에

identity = (__bridge SecIdentityRef)([self _dumpCredentialsOfSecClass:kSecClassIdentity printSelector:@selector(_printIdentity:attributes:)]); 

을 변경이 누군가

하는 데 도움이
0

프로젝트에 좀비 오브젝트를 활성화하려고 했습니까? 그것은 당신이 무엇이 잘못되었는지 알아내는 데 도움이 될 수 있습니다.