pokeb / asi-http-request

Easy to use CFNetwork wrapper for HTTP requests, Objective-C, Mac OS X and iPhone
http://allseeing-i.com/ASIHTTPRequest
Other
5.78k stars 1.41k forks source link

ASIHTTPRequest client certificate failed #408

Open vietnguyen09 opened 7 years ago

vietnguyen09 commented 7 years ago

I have a web server running Nginx with self-signed certificate installed wich is required client certificate who want to access, but when I use ASIHTTPRequest with my client certificate p12 file to request to this server it always fail with message: @"NSLocalizedDescription" : @"A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)"

I'm pretty sure, my client certificate is valid.

Here is my Objective-C code.

+ (NSString *)getRequest:(NSString *)urlString
{
    NSURL *url = [NSURL URLWithString:urlString];

    SecIdentityRef identity = NULL;
    SecTrustRef trust = NULL;
    NSData *PKCS12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"clientcert" ofType:@"p12"]];
    [Mics extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data];

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    [request setClientCertificateIdentity:identity];
    [request setValidatesSecureCertificate:NO];
    [request startSynchronous];

    NSError *error = [request error];
    if (!error) {
        return [request responseString];
    }

    return HTMLError;
}

+ (BOOL)extractIdentity:(SecIdentityRef *)outIdentity andTrust:(SecTrustRef*)outTrust fromPKCS12Data:(NSData *)inPKCS12Data
{
    OSStatus securityError = errSecSuccess;

    NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:@"PasswordOfP12File" forKey:(id)kSecImportExportPassphrase];

    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    securityError = SecPKCS12Import((CFDataRef)inPKCS12Data,(CFDictionaryRef)optionsDictionary,&items);

    if (securityError == 0) {
        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);
        *outIdentity = (SecIdentityRef)tempIdentity;
        const void *tempTrust = NULL;
        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
        *outTrust = (SecTrustRef)tempTrust;
    } else {
        NSLog(@"Failed with error code %d",(int)securityError);
        return NO;
    }
    return YES;
}