willSendRequestForAuthenticationChallenge not called - iphone

I am trying to validate a servers certificate in an iOS application.
The delegate method I am having an issue with is:
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
This method is called when I use a server such as "https://twitter.com".
But, when I point it to my production server (Government CA), this method simply does not get called.
This cert, I guess, can be considered a self-signed cert, because if you do not have the gov certs installed, you get the "This connection is untrusted" message in a browser.
Is there any way to force willSendRequestForAuthenticationChallenge to be called and check the self-signed certificate?
Thanks!

The question has been asked a while ago but I thought I'd give an answer for people to come.
As I understand the authentication challenge is only called once per host every 10 minutes. The result of the challenge is getting cached for performance. The cache expires in 10 minutes. (http://en.wikipedia.org/wiki/Transport_Layer_Security#Resumed_TLS_handshake)
The good insight is given here by jblack who has the reference to Apple forums: How to cancel a persistent connection using NSURLConnection?
When I had a similar question and an issue, the thing that tripped me was that I used the same host for multiple operations in the app, so the challenge has been accepted elsewhere but hasn't expired before my NSURLConnection fired, hence I never got the challenge (had no need).
Try to isolate the host to this one request and then you should get the callback.
Hope it helps.

Related

CBPeripheral being disconnected with UnknownError Code=0 after calling writeValue

I'm developing an app that uses Bluetooth to communicate with Smart Devices.
It needs to authorise iPhone with such scheme:
Scanning devices with some filters of services UUIDs
Connecting to a device, discovering services, discovering characteristics
Calling read operation to retrieve public keys
Exchange received public keys (using ECDH)
Generate token
Write encrypted token (using AES) to device using writeValue
That's all, after that I have stable connection and able to interact with my Smart Device (writing values to protected properties).
The question is that when I restart my app and do all of the steps above, except Step_5 (because I have my token generated and validated previous time), on Step_6 delegate method didWriteValueFor: doesn't even get called, instead of this delegate method didDisconnectPeripheral being called with Error Domain=CBErrorDomain Code=0 "Unknown error." UserInfo={NSLocalizedDescription=Unknown error.} and I can't write values to protected characteristics.
I can't get what I'm doing wrong. Any help would be nice.
UPD[0]: Sometimes I can get a callback for didWriteValueFor: on Step_6 but IMMEDIATELY (like less than a 0.5 sec) iPhone is being disconnected with an error from above.
UPD[1]: Also I was trying to cancelPeripheralConnection() before closing my app because Smart Device does not handle multiple connections in hardware reasons, but no luck here.
UPD[2]: Well, after three days of searching for information, I realized that I was digging in the wrong direction at all. The problem was that I interrupted the application with the “Stop” button in Xcode, and didn’t close it manually via iPhone, therefore, willTerminate was not called, and even if it was called, it had a very limited amount of time to execute all the processes that were supposed to be executed, as a result, the connection didn’t interrupt (the cancelPeripheralConnection method was not called), and the next time I started the App, I tried to establish a connection with a device that already has a connection to my App.
At least it started connecting often, but I'm still getting this error sometimes. The main question is: how properly disconnect from the device? For now I’m unsubscribing from all the properties that have isNotify: true (setting to false) and call cancelPeripheralConnection. Do I need to wait the “unsubscribe” process before disconnecting?
UPD[3]: It doesn't matter if I wait for unsubscribe finished or not. At least it have no effect.
Well, I found the reason why disconnects are appears:
Since Smart Device has several characteristics of public keys that need to be read, encrypted and then sent back, the order keys I read and write was important. Since writeValue and readValue are asynchronous, my order went astray. As soon as I began to keep order, everything worked like a clock.

Bonjour Avahi daemon TXTRecord

I try to use txt-records to share information between multiple devices. Therefore I am using bonjour/avahi. The server-side works fine as wireshark proofs. Information is added to the txt-record and sent out using MDNS.
The problem occurs on the client side, where the daemon/service does not seem to get the information change all the time. It is stuck with information that is already outdated and does not automatically update it when I try to resolve the service again.
On the client side I am using DNSServiceResolve in combination with a callback function where I call TXTRecordContainsKey and TXTRecordGetValuePtr to make sure the data is available before use. This all works fine except that, as already mentioned, the information is not always updated.
Am I missing something, or are there any additional API-function calls that I can use to force the daemon to update its record except DNSServiceResolve?
Thank you in advance.
Solved, always make sure you deaktivate your firewall when dealing with such strange problems...
This completely solved my issue.

Is the asynchronous part of Apple's new verification controller necessary?

I was looking through Apple's Verification Controller patch for In App Purchases here: https://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/_index.html
I was planning on implementing server validation, but to not necessitate a response immediately.
Is the asynchronous part of their new code absolutely necessary. Does it offer any advantage over a naive server side validation?
If I could just use the immediate parsing and checking and gain a benefit, that would be great.
Thanks!
EDIT: This question feels a little empty without some code:
I'm talking specifically about changing the main verifyPurchase function to contain only:
- (BOOL)verifyPurchase:(SKPaymentTransaction *)transaction;
{
return [self isTransactionAndItsReceiptValid:transaction];
}
...and get rid of the client -> server post. Will I still be vulnerable to the recent hacks?
Your question makes much more sense after looking at the code.
The attack in question is that someone presents someone else's otherwise-valid receipt. There does not appear to be anything in the receipt data that ties it to the device/purchaser. You can mitigate this to some extent by checking the purchase dates (but only if the device has accurate time, which is under the user's control).
(This attack would not work if the client generated a 256-bit random nonce which had to match the receipt. An attacker can obviously hack the binary/PRNG, but in either case you've already lost.)
Incidentally, the code has a bunch of problems:
The only check of the server cert is that it's an EV cert. This should be easy to forge, since the attacker has complete control of the CA.
A transaction ID is permanently added to the list of "already seen" transactions in -isTransactionAndItsReceiptValid: before the network check finishes, but the content is only unlocked after the network returns. The receipt can never be re-verified if the connection fails, so the user's money will have effectively gone into a black hole.
It expects the transaction to have occurred on the same device that is verifying it.
It expects ITC_CONTENT_PROVIDER_SHARED_SECRET to be embedded in the executable (trivial to decrypt with a jailbroken device).
It assumes that -connection:didReceiveData: returns the complete receipt data (this might not be the case due to fragmentation, but it can probably be guaranteed since Apple controls the server implementation).

How to check network access to SBJson URL

I'm using SBJson to retrive data from URL. How to check if I have access to the URL before downloading. I want to check this, sometime application crash if there is no network connection.
Here is my code
id response = [self objectWithUrl:[NSURL URLWithString:#"http://myurl.com/Service.svc/GetId"]];
*I'm using stringWithUrl and objectWithUrl method to download the JSON.
Use the Reachability API and use that URL as your hostname you are testing
http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html
//reachabilityWithHostName- Use to check the reachability of a particular host name.
+ (Reachability*) reachabilityWithHostName: (NSString*) hostName;
Do NOT use Reachability on the main thread to detect whether you have a network connection. It doesn't work and can lock up for 30 seconds or more, causing your app to be terminated.
Instead you should simply try downloading the data using an NSURLConnection -- this will power up the radio(s) if needed. You will get a callback if an error occurs.
All network connections -including domain name lookups- should be on secondary threads or asynchronous or at least nonblocking. In the case of NSURLs, use NSURLConnection's asynchronous callbacks.
Your application is probably crashing because you are are making a network call from the main thread and locking up for more than 30 seconds, so the system watchdog timer kills you. Looking at your crash logs in Xcode should verify that. Otherwise, you probably just aren't handling the error condition properly.

No Internet Connection

I am a little confused on how to go about and do this....
On each page of my app i connect to PHP file to drag in data from my server. I have about 10 pages. Now if there is no connection to the internet then of course now data can be received.
Often the app crashes and we are putting this down to not having the data due to a change in connection or wifi whatever.
Now i have setup the reachability thing and that works, but i dont know how to link this in with the PHP calls. Should i check the reachability and if no connection then dont run the call. If so, what about all the variables, they will still be null and cause an error then?
I dont really know what is the best solution.
Hope you can help
Alex
Are the php calls just to receive data from a database without using a built in DB framework such as SQLite? If so, I went the same route to avoid the headache at first, but running SQLite in your app is a better solution overall, and reduces multiple dependencies (such as internet connection).
Now if the php calls that give you data back are receiving this information from yet another source and then feeding it into its own DB.....
Should i check the reachability and if no connection then dont run the call
Yes you should. This is done in multiple apps already. What variables would be null in this case? Pop the code that makes the call in an "if" block below this check, and only run it if true. Error handling other variables that might be null because the php call isn't setting them is up to you. You can do this is multiple ways.
You should certainly cache the data so the App doesn't HAVE to connect to the internet to display something, other than that I would make sure to use asynchronous requests and the timeout feature of NSURLRequest to control your attempts to request data in the background. If you don't get the data, just keep using what you have cached.