OpenSSL "Server" localhost "requires a client certificate.": IOS 8 with apache server localhost

I am facing the problem of creating and installing OpenSSL certificate, or it might be related to NSURLConnection, I created OpenSSL certificate after that .

Here is a localized error

2015-07-24 14:47:32.279 SSLTest[7657:60489] CFNetwork SSLHandshake failed (-9824 -> -9829)
2015-07-24 14:47:32.347 SSLTest[7657:60489] NSURLConnection/CFURLConnection       
HTTP load failed (kCFStreamErrorDomainSSL, -9829)
2015-07-24 14:47:32.576 SSLTest[7657:60350] The server "localhost" requires a client certificate.

      

Every time I get the error "Server" localhost "requires a client certificate".

Here is my .m

- (void)viewDidLoad
{
   [super viewDidLoad];

   NSString *url = @"https://localhost/Test.php";

   NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
   [theRequest setHTTPMethod:@"POST"];

   NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
   [theConnection start];
}

#pragma mark - NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{    
    if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
       [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    } else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {

       SecIdentityRef identity = [self getClientCertificate];
       SecCertificateRef certificateRef;
       SecIdentityCopyCertificate(identity, &certificateRef);
       CFArrayRef certificateArray = CFArrayCreate(NULL, (const void **)certificateRef, 1, NULL);

       NSURLCredential *identityCredential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray *)certificateArray persistence:NSURLCredentialPersistenceForSession];
       [challenge.sender useCredential:identityCredential forAuthenticationChallenge:challenge];
   }
 }

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
   NSLog(@"%@",[error localizedDescription]);
}

#pragma mark - Certificates

- (SecIdentityRef)getClientCertificate {
    SecIdentityRef identityApp = nil;
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
    CFStringRef password = CFSTR("abcXYZ123");
    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);
} else {
    NSLog(@"Error opening Certificate.");
}
return identityApp;
}

      

My httpd.config looks like this (I have BITNAMI XAMPP 5.6.8 on my local mac-mini system)

Alias /bitnami/ "/Applications/XAMPP/xamppfiles/apache2/htdocs/"
Alias /bitnami "/Applications/XAMPP/xamppfiles/apache2/htdocs"


SSLEngine on
SSLCertificateFile /Applications/XAMPP/xamppfiles/apache2/htdocs/ca.crt
SSLCertificateKeyFile /Applications/XAMPP/xamppfiles/apache2/htdocs/ca_withoutPassword.key

SSLCACertificateFile /Applications/XAMPP/xamppfiles/apache2/htdocs/ca.crt

SSLVerifyClient require

<Directory "/Applications/XAMPP/xamppfiles/apache2/htdocs">
   Options Indexes FollowSymLinks
   AllowOverride All
   Order allow,deny
   Allow from all
</Directory>

      

I've tried with SSLCertificateChainFile and SSLCACertificateFile but no luck.

If I remove the 'SSLVerifyClient Require' and delete the service, then I get authenticationMethod 'NSURLAuthenticationMethodServerTrust' and the server response as expected .

If I add 'SSLVerifyClient require' to .config file then NSURLConnection delegate method is sentRequestForAuthenticationChallenge ' will call twice, once with ' NSURLAuthenticationMethodServerTrust ' and second time with ' NSURLAuthenticationMethodClientCertificate ' above and then I get errors above

+3


source to share


1 answer


I think your Apache installation is wrong; You are pointing SSLCACertificateFile

to a client certificate, and the client certificate only needs to be on the client side; Instead, you must point it to the CA certificate. This is what is used to validate the client certificate.



As a side note, your configuration above is REALLY insecure. Never put SSL certificates in your htdocs public folder. They have to be hosted somewhere read-only by root and are definitely not accessible to remote users anywhere. Thus, you expose yourself to the worst kind of attacks.

0


source







All Articles