I am trying to read certificates from various URLs in iOS. My code however is not working well – the array that should return the information I need always returns null.
What am I missing?
- (void)findCertificate:(NSString *)url
{
NSInputStream*input = [[NSInputStream inputStreamWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://store.writeitstudios.com"]]] retain];
[input setDelegate:self];
[input scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[input open];
NSLog(@"Status: %i",[input streamStatus]);
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
NSLog(@"handle Event: %i",eventCode);
if (eventCode == NSStreamStatusOpen)
{
NSArray *certificates = (NSArray*)CFReadStreamCopyProperty((CFReadStreamRef)aStream, kCFStreamPropertySSLPeerCertificates);
NSLog(@"Certs: %@",CFReadStreamCopyProperty((CFReadStreamRef)aStream, kCFStreamPropertySSLPeerCertificates));
if ([certificates count] > 0) {
SecCertificateRef certificate = (SecCertificateRef)[certificates objectAtIndex:0];
NSString *description = (NSString*)SecCertificateCopySubjectSummary(certificate);
NSData *data = (NSData *)SecCertificateCopyData(certificate);
NSLog(@"Description: %@",description);
}
}
}
And yes, I am aware that I am leaking memory. This is just a snippet.
Let me explain what you’re doing here and why it’s wrong:
NSData(a data buffer). Note that you are not loading any certificates (well, technicallyNSURLwill load them internally, but this code is most definitely not putting them into theNSData)NSStream‘s delegate methodstream:handleEvent:and are attempting to read the kCFStreamPropertySSLPeerCertificates property. This property will be empty since the stream contains only a bit of HTML data, nothing else.NSArray.NULL.Using
NSStream/CFStreamis not necessary for the task at hand. And most definitely you don’t have to go throughNSURLConnectionfirst and then throughNSStream.To retrieve SSL server certificates, stick to a simple, asynchronous
NSURLConnectionand use its delegate methods to access the certificates: