开发者

Reading Certificates on iOS Problem

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:(NSStri开发者_StackOverflowng *)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:

  1. You are loading the contents of the URL https://store.writeitstudios.com (i.e. the HTML) synchronously into an NSData (a data buffer). Note that you are not loading any certificates (well, technically NSURL will load them internally, but this code is most definitely not putting them into the NSData)
  2. You are opening an input stream and sticking the data (a bit of HTML, no certificates!) into it.
  3. You have implemented NSStream's delegate method stream: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.
  4. You are casting the empty property to an NSArray.
  5. The loop is not executed because the array is NULL.

Using NSStream/CFStream is not necessary for the task at hand. And most definitely you don't have to go through NSURLConnection first and then through NSStream.

To retrieve SSL server certificates, stick to a simple, asynchronous NSURLConnection and use its delegate methods to access the certificates:

// Method to begin the asynchronous download

- (void)beginCertificateDownload:(NSURL *)url
{
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [connection start];
}

// NSURLConnection Delegate Methods

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace 
{
    return [[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    // extract the certificates
    SecTrustRef trustRef = [[challenge protectionSpace] serverTrust];
    CFIndex count = SecTrustGetCertificateCount(trustRef);
    for (CFIndex i = 0; i < count; i++) {
        SecCertificateRef certRef = SecTrustGetCertificateAtIndex(trustRef, i);
        CFStringRef certSummary = SecCertificateCopySubjectSummary(certRef); 
        NSLog(@"%@", certSummary);

        // do whatever you need with the certificates here
        // don't forget to copy them if you need to keep them
        // around beyond the scope of this method
    }

    // I'm assuming you're not interested in actually loading the contents of the URL, so cancel
    [[challenge sender] cancelAuthenticationChallenge:challenge];

    // you'll also want to release the connection object at some point
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜