//服务器端证书由AFSecurityPolicy 读取
//重写这个方法就能提供客户端验证
[managersetSessionDidBecomeInvalidBlock:^(NSURLSession *_Nonnull session,NSError * _Nonnull error) {
NSLog(@"setSessionDidBecomeInvalidBlock");
}];
[manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession*session,NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing*_credential) {
NSURLSessionAuthChallengeDisposition disposition =NSURLSessionAuthChallengePerformDefaultHandling;
__autoreleasingNSURLCredential *credential =nil;
if([challenge.protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust]) {
if([manager.securityPolicyevaluateServerTrust:challenge.protectionSpace.serverTrustforDomain:challenge.protectionSpace.host]) {
credential = [NSURLCredentialcredentialForTrust:challenge.protectionSpace.serverTrust];
if(credential) {
disposition =NSURLSessionAuthChallengeUseCredential;
}else {
disposition =NSURLSessionAuthChallengePerformDefaultHandling;
}
}else {
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
}else {
// client authentication
SecIdentityRef identity =NULL;
SecTrustRef trust =NULL;
NSString *p12 = [[NSBundlemainBundle]pathForResource:@"client.key"ofType:@"p12"];
NSFileManager *fileManager =[NSFileManagerdefaultManager];
if(![fileManagerfileExistsAtPath:p12])
{
NSLog(@"client.p12:not exist");
}
else
{
NSData *PKCS12Data = [NSDatadataWithContentsOfFile:p12];
if ([[weakSelfclass]extractIdentity:&identityandTrust:&trustfromPKCS12Data:PKCS12Data])
{
SecCertificateRef certificate =NULL;
SecIdentityCopyCertificate(identity, &certificate);
constvoid*certs[] = {certificate};
CFArrayRef certArray =CFArrayCreate(kCFAllocatorDefault, certs,1,NULL);
credential =[NSURLCredentialcredentialWithIdentity:identitycertificates:(__bridge NSArray*)certArraypersistence:NSURLCredentialPersistencePermanent];
disposition =NSURLSessionAuthChallengeUseCredential;
}
}
}
*_credential = credential;
return disposition;
}];
+(BOOL)extractIdentity:(SecIdentityRef*)outIdentity andTrust:(SecTrustRef *)outTrust fromPKCS12Data:(NSData *)inPKCS12Data {
OSStatus securityError =errSecSuccess;
//client certificate password
NSDictionary*optionsDictionary = [NSDictionarydictionaryWithObject:@"123456"
forKey:(__bridgeid)kSecImportExportPassphrase];
CFArrayRef items =CFArrayCreate(NULL,0,0, NULL);
securityError =SecPKCS12Import((__bridgeCFDataRef)inPKCS12Data,(__bridgeCFDictionaryRef)optionsDictionary,&items);
if(securityError ==0) {
CFDictionaryRef myIdentityAndTrust =CFArrayGetValueAtIndex(items,0);
constvoid*tempIdentity =NULL;
tempIdentity=CFDictionaryGetValue (myIdentityAndTrust,kSecImportItemIdentity);
*outIdentity = (SecIdentityRef)tempIdentity;
constvoid*tempTrust =NULL;
tempTrust =CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemTrust);
*outTrust = (SecTrustRef)tempTrust;
}else {
NSLog(@"Failedwith error code %d",(int)securityError);
returnNO;
}
return YES;
}