Lorsque j'utilise l'authentification par certificate client, pourquoi continue-t-on à get NSURLErrorDomain Code = -1206?

Le code suivant est moi en utilisant le code des publications précédentes sur l'authentification du certificate client ios. Tout le monde dit que cela fonctionne, mais pourquoi ça marche pour moi?!?!

Je continue à recevoir l'erreur suivante:

connection didFailWithError: Error Domain=NSURLErrorDomain Code=-1206 "The server “www.mywebsite.com” requires a client certificatee. 

J'ai suivi au less 4 messages sur ce même sujet sur stackoverflow et 2 sur d'autres sites similaires. Ils disent tous la même chose, sauf que ça ne marche pas.

Je sais que mon file PKCS12 fonctionne parce que je l'ai envoyé par e-mail à mon ipad, où je l'ai installé sur le trousseau d'ipad et je peux accéder et autoriser avec l'identité de certificate utilisant Safari. C'est juste quand j'essaye de le faire en utilisant un NSURLConnection dans une application tierce, il refuse de me permettre de le faire.

Toutes les suggestions sont les bienvenues, j'ai l'printing d'avoir épuisé mes options.


  // Download PKCS12 Cert from my FTP server. NSSsortingng *ssortingngURL = @"ftp://user:password@myipaddress/myclientId.p12"; NSSsortingng* webSsortingngURL = [ssortingngURL ssortingngByAddingPercentEscapesUsingEncoding:NSUTF8SsortingngEncoding]; NSURL *url = [NSURL URLWithSsortingng:webSsortingngURL]; NSData *p12Data = [NSData dataWithContentsOfURL:url]; if ( p12Data ) { CFDataRef inP12data = (__bridge CFDataRef)p12Data; SecIdentityRef myIdentity; SecTrustRef myTrust; OSStatus errMsg = NULL; // This is the same function that has been repostd in all the other posts about ios client certificateion authentication. So i'm not going to repost that. errMsg = extractIdentityAndTrust(inP12data, &myIdentity, &myTrust); SecCertificateRef myCertificate; SecIdentityCopyCertificate(myIdentity, &myCertificate); const void *certs[] = { myCertificate }; CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL); NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificatees:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistenceNone]; [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 

L'erreur était sur cette ligne. Le deuxième paramètre doit être réglé sur "zéro"

  NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificatees:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistenceNone]; 

Changé en:

  NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificatees:nil persistence:NSURLCredentialPersistenceNone]; 

Les chances sont que votre .p12 contient des certificates intermédiaires et votre server a besoin de ces certificates intermédiaires.

Vous pouvez vérifier avec wireshark que votre code enverra un certificate dupliqué de l'identité mais pas de certificate intermédiaire dans la réponse du certificate client.

Si tel est le cas, vous devez également extraire le certificate de p12 et le transmettre pour créer les NSURLCredentials:

 int count = SecTrustGetCertificateCount(myTrust); NSMutableArray* myCertificates = nil; if (count > 1) { myCertificates = [NSMutableArray arrayWithCapacity:SecTrustGetCertificateCount(myTrust)]; for (int i = 1; i < count; ++i) { // remove the leaf cert [certs addObject:(id)SecTrustGetCertificateAtIndex(myTrust, i)]; } } NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificatees:myCertificates persistence:NSURLCredentialPersistenceNone]; 

De même, passer nil à NSURLCredential ne doit pas casser de code. voir l'exemple d'Apple: https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html . Mais passer le tableau vide @ [] à NSURLCredential va planter.