2009-09-22 46 views
20

Tôi đang chiến đấu với xác thực chứng chỉ ứng dụng khách. Khi một máy chủ cần có một chứng chỉ (giấy chứng nhận trong trường hợp này), phương pháp này được gọi từ NSURLConnection đại biểu:iPhone: Xác thực chứng chỉ ứng dụng khách HTTPS

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

Tôi muốn tải một chứng chỉ từ một tập tin, điền vào một chứng chỉ và chạy phương pháp này:

[[challenge sender] useCredential:[self credential] forAuthenticationChallenge:challenge]; 

Nhưng tôi không biết làm thế nào để khởi tạo (hoặc điền) một tham số SecIdentityRef. Đây là mã của tôi tạo thông tin đăng nhập:

NSString *certPath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"]; 
NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath]; 

SecIdentityRef myIdentity; // ??? 

SecCertificateRef myCert = SecCertificateCreateWithData(NULL, (CFDataRef)certData); 
[certData release]; 
SecCertificateRef certArray[1] = { myCert }; 
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL); 
CFRelease(myCert); 
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity 
            certificates:(NSArray *)myCerts 
            persistence:NSURLCredentialPersistencePermanent]; 
CFRelease(myCerts); 

Có ai biết cách giải quyết không? Cảm ơn.


cuối cùng tôi đã tìm thấy các giải pháp, nhưng một vấn đề mới là ở đây:

khách hàng của tôi không gửi giấy chứng nhận cho máy chủ. Sau khi máy chủ yêu cầu chứng chỉ, các ứng dụng chạy phương pháp này:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

và tôi điền vào chứng chỉ (giống như tôi đã đề cập ở trên), nhưng kết nối kết thúc với một lỗi: NSURLErrorDomain -1206. Theo nhật ký máy chủ, chứng chỉ ứng dụng khách không được gửi bởi ứng dụng.

Có ai có kinh nghiệm với hành vi này không? Tôi có cần bằng cách nào đó xác minh chứng chỉ trong ứng dụng không? Hoặc bất cứ điều gì khác để làm cho nó hoạt động? Tôi có thể cung cấp mã hiện tại của tôi nếu nó giúp. Thanks cho bất kỳ ý tưởng ...

Trả lời

0

Tất nhiên vấn đề là với các mô phỏng iPhone trong xcode :) Sau khi cập nhật lên phiên bản 3.1 nó bắt đầu làm việc ...

+3

Chỉ cần một mẹo để làm cho câu hỏi của bạn dễ đọc hơn: dont bài câu hỏi như câu trả lời mới. Nó có xu hướng làm cho các chủ đề khó đọc hơn. Hãy nhớ rằng câu hỏi của bạn có thể sẽ hữu ích cho người khác và điều quan trọng là họ có thể xem quy trình của bạn và câu trả lời cuối cùng. Cảm ơn! – mtmurdock

4

tôi sử dụng các bước sau:

  1. chiết xuất SecIdentityRef từ tập tin giấy chứng nhận sử dụng pkcs12 SecPKCS12Import chức năng
  2. chức năng sử dụng SecIdentityCopyCertificate để có được SecCertificateRef

và t anh ấy nghỉ ngơi (khởi tạo thông tin xác thực) giống như trong câu hỏi của tôi ... Tôi có thể đặt thêm mã này nếu bạn muốn. Lưu ý rằng có lỗi (http://openradar.appspot.com/7090030) trong trình mô phỏng iphone, vì vậy không thể làm việc với nhiều chứng chỉ trong trình mô phỏng.

1

Bạn cũng có thể tìm kiếm bản sắc trong keychain nếu bạn lưu trữ thông tin này có:

+ (SecIdentityRef)dumpSecIdentityRef 
{ 
OSStatus err; 
CFArrayRef result; 
CFIndex  resultCount; 
CFIndex  resultIndex; 

result = NULL; 
err = SecItemCopyMatching((__bridge CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys: 
                 (__bridge id)kSecClassIdentity, 
                 kSecClass, kSecMatchLimitAll, 
                 kSecMatchLimit, kCFBooleanTrue, 
                 kSecReturnRef, kCFBooleanTrue, 
                 kSecReturnAttributes, nil], 
          (CFTypeRef *) &result); 

if ((result != NULL) && (err == noErr)) { 

    NSMutableArray *identitiesArray = [NSMutableArray new]; 

    resultCount = CFArrayGetCount(result); 
    for (resultIndex = 0; resultIndex < resultCount; resultIndex++) { 
     NSDictionary * thisResult; 
     thisResult = (__bridge NSDictionary *) CFArrayGetValueAtIndex(result, resultIndex); 
     NSLog(@"%@", (__bridge id)(result)); 
     [identitiesArray addObject:thisResult]; 
    } 

    CFRelease(result); 
    //TO DO - choose correct identity object from array. 
    SecIdentityRef myIdentity = (__bridge SecIdentityRef)([[identitiesArray objectAtIndex:0] valueForKey:@"v_Ref"]); 

    return myIdentity; 
} 
return nil; 
} 
Các vấn đề liên quan