How to import a SSL certificate into my Application's keychain - iphone

I want to import a SSL certificate into my Application's keychain. I got a sample project from apple and I tested it. I am sure that technically it can be done. But my question is that, what kind of approach should I use while asking the client to install the certificate. I thought about the following options,
->Prompting the user to install the credentials at the application launch.
->Maintaining a settings page to control the credentials.
As my application totally depends upon web services I cannot proceed without the credentials. Please post your suggestions.

Ask your certificate provider for a link to download the certificate. Just Download and Store the certificate in your resources folder.
The below set of code snippets will do the work for you. Please post comments if you don't understand the below.
SecIdentityRef identity = NULL;
SecTrustRef trust = NULL;
NSData *PKCS12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"test_iphone_services" ofType:#"p12"]];
//Calling the method
[Child extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data]
+ (BOOL)extractIdentity:(SecIdentityRef *)outIdentity andTrust:(SecTrustRef*)outTrust fromPKCS12Data:(NSData *)inPKCS12Data
{
OSStatus securityError = errSecSuccess;
//testtest is the passsword for the certificate.
NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:#"testtest" 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;
}
#pragma mark - NSURLConnection Delegate Methods
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(#"trust %#", trust);
NSURLCredential *credential;
NSURLCredentialPersistence persistence;
persistence = NSURLCredentialPersistencePermanent;
credential = [NSURLCredential credentialWithIdentity:identity certificates:nil persistence:persistence];
NSLog(#"credential %#", credential);
[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
}

Related

How to get user details using twitter api v1.1 (Twitter error 215)

I have used the twitter api provided by twitter,to get the details but
not able to execute it, even tried to pass the authentication data
like consumer secret key, consumer key, token but the result is same.
I am able to login and receiving twitter authentication token but not able to get user details.
Below code is used by me (I am using MGtwitter engine) :
NSMutableURLRequest *request =[[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://api.twitter.com/1.1/users/show.json?screen_name=%#",username]]];
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil ];
NSString *returnString = [[NSString alloc]initWithData:returnData encoding:NSUTF8StringEncoding];
NSError *err = nil;
twitterLogin = [NSJSONSerialization JSONObjectWithData:[returnString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&err];
Error is shown as below:
errors = (
{
code = 215;
message = "Bad Authentication data";
} );
First, you need to Authenticate your request (Get permission).
second, see follow these steps:
1.Download FHSTwitterEngine Twitter Library.
2.Add the folder FHSTwitterEngine" to your project and #import "FHSTwitterEngine.h".
3.add SystemConfiguration.framework to your project.
Usage : 1.in the [ViewDidLoad] add the following code.
UIButton *logIn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
logIn.frame = CGRectMake(100, 100, 100, 100);
[logIn setTitle:#"Login" forState:UIControlStateNormal];
[logIn addTarget:self action:#selector(showLoginWindow:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:logIn];
[[FHSTwitterEngine sharedEngine]permanentlySetConsumerKey:#"<consumer_key>" andSecret:#"<consumer_secret>"];
[[FHSTwitterEngine sharedEngine]setDelegate:self];
and don't forget to import the delegate FHSTwitterEngineAccessTokenDelegate.
you need to get the permission for your request, with the following method which will present Login window:
- (void)showLoginWindow:(id)sender {
[[FHSTwitterEngine sharedEngine]showOAuthLoginControllerFromViewController:self withCompletion:^(BOOL success) {
NSLog(success?#"L0L success":#"O noes!!! Loggen faylur!!!");
}];
}
when the Login window is presented, enter your Twitter Username and Password to authenticate your request.
add the following methods to your code:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[FHSTwitterEngine sharedEngine]loadAccessToken];
NSString *username = [[FHSTwitterEngine sharedEngine]loggedInUsername];// self.engine.loggedInUsername;
if (username.length > 0) {
lbl.text = [NSString stringWithFormat:#"Logged in as %#",username];
[self listResults];
} else {
lbl.text = #"You are not logged in.";
}
}
- (void)storeAccessToken:(NSString *)accessToken {
[[NSUserDefaults standardUserDefaults]setObject:accessToken forKey:#"SavedAccessHTTPBody"];
}
- (NSString *)loadAccessToken {
return [[NSUserDefaults standardUserDefaults]objectForKey:#"SavedAccessHTTPBody"];
}
4.Now you are ready to get your request, with the following method(in this method I created a Twitter search for some Hashtag, to get the screen_name for example):
- (void)listResults {
dispatch_async(GCDBackgroundThread, ^{
#autoreleasepool {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// the following line contains a FHSTwitterEngine method wich do the search.
dict = [[FHSTwitterEngine sharedEngine]searchTweetsWithQuery:#"#iOS" count:100 resultType:FHSTwitterEngineResultTypeRecent unil:nil sinceID:nil maxID:nil];
// NSLog(#"%#",dict);
NSArray *results = [dict objectForKey:#"statuses"];
// NSLog(#"array text = %#",results);
for (NSDictionary *item in results) {
NSLog(#"text == %#",[item objectForKey:#"text"]);
NSLog(#"name == %#",[[item objectForKey:#"user"]objectForKey:#"name"]);
NSLog(#"screen name == %#",[[item objectForKey:#"user"]objectForKey:#"screen_name"]);
NSLog(#"pic == %#",[[item objectForKey:#"user"]objectForKey:#"profile_image_url_https"]);
}
dispatch_sync(GCDMainThread, ^{
#autoreleasepool {
UIAlertView *av = [[UIAlertView alloc]initWithTitle:#"Complete!" message:#"Your list of followers has been fetched" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
});
}
});
}
That's all.
I just got the screen_name from a search Query, you can get a timeline for a user using the following methods:
// statuses/user_timeline
- (id)getTimelineForUser:(NSString *)user isID:(BOOL)isID count:(int)count;
- (id)getTimelineForUser:(NSString *)user isID:(BOOL)isID count:(int)count sinceID:(NSString *)sinceID maxID:(NSString *)maxID;
instead of the search method above.
Note: see the FHSTwitterEngine.h to know what method you need to use.
Note: to get the <consumer_key> and the <consumer_secret> you need to to visit this link
to register your app in Twitter.
Got the solution after MKAlatrash revert, to get the user profile follow certain steps in the code as under :
[[FHSTwitterEngine sharedEngine]getProfileImageForUsername:username andSize:FHSTwitterEngineImageSizeNormal];
jump to definition of this function and replace the if ... else if part
if ([userShowReturn isKindOfClass:[NSError class]]) {
return [NSError errorWithDomain:[(NSError *)userShowReturn domain] code:[(NSError *)userShowReturn code] userInfo:[NSDictionary dictionaryWithObject:request forKey:#"request"]];
NSLog(#"user show return %#",userShowReturn);
} else if ([userShowReturn isKindOfClass:[NSDictionary class]]) {
return userShowReturn;
NSString *url = [userShowReturn objectForKey:#"profile_image_url"]; // normal
if (size == 0) { // mini
url = [url stringByReplacingOccurrencesOfString:#"_normal" withString:#"_mini"];
} else if (size == 2) { // bigger
url = [url stringByReplacingOccurrencesOfString:#"_normal" withString:#"_bigger"];
} else if (size == 3) { // original
url = [url stringByReplacingOccurrencesOfString:#"_normal" withString:#""];
}
id ret = [self sendRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
if ([ret isKindOfClass:[NSData class]]) {
return [UIImage imageWithData:(NSData *)ret];
}
return ret;
}
That really was helpful thanks

get pfx file included in a mobilecertificate in iOS

I'm trying to connect to a server using a .pfx that is stored in a .mobileconfig file on my iPhone.
When the server ask for it in
-(void)connection:(NSURLConnection*)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge{
How can I create the NSURLCredential with the .pfx? Should I use
+ (NSURLCredential *)credentialWithIdentity:(SecIdentityRef)identity certificates:(NSArray *)certArray persistence:(NSURLCredentialPersistence)persistence
If thats the case, how do I extract the .pfx to put it into the array.
Thanks in advance.
So no, there is no way to get the certificate from the mobileconfig file. iOS applications use its own keychain access and storage. Only email and other phone service like internet can make use of those certificates
U can use my code:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"torbix" ofType:#"pfx"];
NSData *pfxdata = [NSData dataWithContentsOfFile:path];
CFDataRef inpfxdata = (CFDataRef)pfxdata;
SecIdentityRef myIdentity;
SecTrustRef myTrust;
OSStatus status = extractIdentityAndTrust(inpfxdata, &myIdentity, &myTrust);
SecCertificateRef myCertificate;
SecIdentityCopyCertificate(myIdentity, &myCertificate);
const void *certs[] = { myCertificate };
CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity
certificates:(NSArray *)myCertificate
persistence:NSURLCredentialPersistencePermanent];
[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
CFRelease(myIdentity);
CFRelease(myCertificate);
CFRelease(certsArray);
}
//extractIdentityAndTrust method.
-(OSStatus) extractIdentityAndTrust:(CFDataRef)inpfxdata identity:(SecIdentityRef *)identity trust:(SecTrustRef *)trust
{
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inpfxdata, options, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;
}
if (options) {
CFRelease(options);
}
return securityError;
}
good luck!^-^

How to make iPhoneHTTPServer secure server

I am very new to iPhone development.
I downloaded the iPhoneHTTPServer application from bellow link.
https://github.com/robbiehanson/CocoaHTTPServer/tree/master/Samples/iPhoneHTTPServer
It works fine for HTTP request.
Now I want to make it as a secure server. (use HTTPS)
for that I have override following two methods in MyHTTPConnection.m
I am sure about changes in this method:
/**
* Overrides HTTPConnection's method
**/
- (BOOL)isSecureServer
{
// Create an HTTPS server (all connections will be secured via SSL/TLS)
return YES;
}
I need to apply changes in bellow method: (Please guide me here.)
PROBLEM : DDKeychain and Cocoa.h is not available for iOS.
/**
* Overrides HTTPConnection's method
*
* This method is expected to returns an array appropriate for use in
* kCFStreamSSLCertificates SSL Settings.
* It should be an array of SecCertificateRefs except for the first element in
* the array, which is a SecIdentityRef.
**/
- (NSArray *)sslIdentityAndCertificates
{
NSArray *result = [DDKeychain SSLIdentityAndCertificates];
if([result count] == 0)
{
[DDKeychain createNewIdentity];
return [DDKeychain SSLIdentityAndCertificates];
}
return result;
}
I have solved issue with following steps:
Export certificate from your Keychain Access(Mac OS X)
Open Keychain Access
Select Certificate, Right click and select Export...
Export Certificate with file format : Personal Information Exchange (.p12)
Provide name and password to export file.
FileName: TestCertificate.p12
Password: test123 (* try your admin login pass if not worked)
Import TestCertificate.p12 in you XCode project.
Add Security.framework in your project.
Import Security.h file in you code.
#import <Security/Security.h>
Override and change sslIdentityAndCertificates method as bellow.
/**
* Overrides HTTPConnection's method
*
* This method is expected to returns an array appropriate for use in kCFStreamSSLCertificates SSL Settings.
* It should be an array of SecCertificateRefs except for the first element in the array, which is a SecIdentityRef.
**/
- (NSArray *)sslIdentityAndCertificates
{
SecIdentityRef identityRef = NULL;
SecCertificateRef certificateRef = NULL;
SecTrustRef trustRef = NULL;
NSString *thePath = [[NSBundle mainBundle] pathForResource:#"TestCertificate" ofType:#"p12"];
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;
CFStringRef password = CFSTR("test123");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = errSecSuccess;
securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);
identityRef = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
trustRef = (SecTrustRef)tempTrust;
} else {
NSLog(#"Failed with error code %d",(int)securityError);
return nil;
}
SecIdentityCopyCertificate(identityRef, &certificateRef);
NSArray *result = [[NSArray alloc] initWithObjects:(id)identityRef, (id)certificateRef, nil];
return result;
}

iOS 4.3 extractIdentityAndTrust linking error

I'm having a problem using extractIdentityAndTrust in iOS and getting the following linking error. I'm just trying to follow the code from the 'Certificate,Key and trust programming guide' and have a PKCS#12 certificate in the bundle.
"_extractIdentityAndTrust", reference from:
[cryptoViewController viewDidLoad] in cryptoViewController.o
Symbol(s) not found
Collect2: Id returneed 1 exit status
I've the following code in the project;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *thePath = [[NSBundle mainBundle]
pathForResource:#"iphone-cert" ofType:#"p12"];
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;
CFDataRef inPKCS12Data1 = (CFDataRef)PKCS12Data;
OSStatus status = noErr;
SecIdentityRef myIdentity;
SecIdentityRef *outIdentity;
SecTrustRef *outTrust;
SecTrustRef myTrust;
status = extractIdentityAndTrust(
inPKCS12Data1,
&myIdentity,
&myTrust);
if (status != 0)
{
}
SecTrustResultType trustResult;
if (status == noErr)
{
status = SecTrustEvaluate(myTrust, &trustResult);
}
if (trustResult == kSecTrustResultRecoverableTrustFailure)
{
}
OSStatus extractIdentityAndTrust(CFDataRef inPKCS12Data,
SecIdentityRef *outIdentity,
SecTrustRef *outTrust);
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("Password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(
NULL, keys,
values, 1,
NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
CFDataRef inPKCS12Data2 = (CFDataRef)PKCS12Data;
securityError = SecPKCS12Import(inPKCS12Data2,
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;
if (optionsDictionary)
CFRelease(optionsDictionary);
[PKCS12Data release];
}
//Next part
SecCertificateRef myReturnedCertificate = NULL;
SecIdentityRef myReturnedIdentity;
status = SecIdentityCopyCertificate (myReturnedIdentity,
&myReturnedCertificate);
CFStringRef certSummary = SecCertificateCopySubjectSummary
(myReturnedCertificate);
NSString* summaryString = [[NSString alloc]
initWithString:(NSString*)certSummary]; //
NSLog(#"%#", summaryString);
[summaryString release];
}
and the following declaration in the header file;
OSStatus extractIdentityAndTrust(CFDataRef inPKCS12Data,
SecIdentityRef *outIdentity, SecTrustRef *outTrust);
Has anyone got any advice?
I'm not sure, but it seams that this method is not available on iOS.
Anyway the proper way to get the identity and certificates from a p12 file is:
Use the SecPKCS12Import() function to import the p12 data.
This will return an NSArray containing NSDictionary objects.
The identity is stored within the dictionary under the key 'kSecImportItemIdentity'
An NSArray of certificates is stored under 'kSecImportItemCertChain'
The things get a little bit complicated if you have multiple identities in your p12 file. Then you need to have some logic on how to choose the right one. But for start just get the dictionary at index 0 from the array returned at step 1 ;-)
Regards,
Pece

NSURLConnection SSL HTTP Basic Auth

I am unable to get a url request to do both ssl urls and basic authentication. I did check the other related questions and they dont seem to work
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
// NSLog(#"We are checking protection Space!");
if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(#"Can Auth Secure Requestes!");
return YES;
}
else if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic])
{
NSLog(#"Can Auth Basic Requestes!");
return YES;
//return NO;
}
NSLog(#"Cannot Auth!");
return NO;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(#"Trust Challenge Requested!");
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
else if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic])
{
NSLog(#"HTTP Auth Challenge Requested!");
NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:#"user" password:#"pass" persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
[credential release];
}
Can't seem to figure out what im doing wrong here. The Connection description says Secure Connection Failed. I have tried with simply ssl and no basic it works fine. I have also tried without ssl and basic and it works fine.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
return YES;
}
else
{
if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic])
{
return YES;
}
}
return NO;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
else
{
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic])
{
NSURLCredential *creden = [[NSURLCredential alloc] initWithUser:#"USERNAME" password:#"PASSWORD" persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:creden forAuthenticationChallenge:challenge];
[creden release];
}
else
{
[[challenge sender]cancelAuthenticationChallenge:challenge];
}
}
}
It works fine actually, the problem had to do with the SSL certificate.
I think the accepted answer may end up incorrectly trusting invalid server certificates, as it doesn't validate the server trust.
Apple's documentation for NSURLCredential credentialForTrust: indicates that you should actually validate the server trust before you use it:
Before creating a server trust credential, it is the responsibility of the delegate of an NSURLConnection object or an NSURLDownload object to evaluate the trust. Do this by calling SecTrustEvaluate, passing it the trust obtained from the serverTrust method of the server’s NSURLProtectionSpace object. If the trust is invalid, the authentication challenge should be cancelled with cancelAuthenticationChallenge:.
Apple's documentation for NSURLAuthenticationChallenge also indicates how a challenge's proposedCredential should be taken into account.
Taking this into account would yield (ARC) code something like this:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
{
if (challenge.proposedCredential)
{
if (challenge.previousFailureCount == 0)
{
[challenge.sender useCredential:challenge.proposedCredential forAuthenticationChallenge:challenge];
}
else
{
// The server has rejected the proposed credential, and
// you should use that credential to populate a password
// or certificate chooser dialog, then provide a new credential.
// You can create password-based credentials by calling the
// credentialWithUser:password:persistence: method or create
// certificate-based credentials with the
NSLog(#"Need to add code here to create new credential...");
}
}
else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(#"Trust Challenge Requested!");
// As per NSURLCredential class reference, verify the server trust...
SecTrustResultType trustResult = kSecTrustResultInvalid;
const OSStatus status = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResult);
if (noErr == status &&
(
kSecTrustResultProceed == trustResult ||
// https://developer.apple.com/library/mac/qa/qa1360/_index.html
kSecTrustResultUnspecified == trustResult
)
)
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
else
{
NSLog(#"Failed to verify server trust, cancelling...");
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}
else if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic])
{
NSLog(#"HTTP Auth Challenge Requested!");
NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:#"user" password:#"pass" persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}