[CDRIVER-2825] Connecting with an invalid cert path secure transport hangs Created: 14/Sep/18  Updated: 28/Oct/23  Resolved: 22/Oct/18

Status: Closed
Project: C Driver
Component/s: tls
Affects Version/s: None
Fix Version/s: 1.14.0

Type: Bug Priority: Major - P3
Reporter: Kevin Albertson Assignee: A. Jesse Jiryu Davis
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Text File CDRIVER-2825.patch    
Issue Links:
Related
related to CDRIVER-2844 Some errors ignored when loading cert... Backlog

 Description   

Supplying the wrong path to a certificate for DarwinSSL seems to hang indefinitely on this line:

dataref = SecTransformExecute (sec_transform, &error);

Instead, we should log an error if possible, like we do for OpenSSL.



 Comments   
Comment by Githook User [ 22/Oct/18 ]

Author:

{'name': 'A. Jesse Jiryu Davis', 'email': 'jesse@mongodb.com', 'username': 'ajdavis'}

Message: CDRIVER-2825 handle missing PEM with Darwin SSL
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/75ccf0f5ef9e2a9085f6b4c009574a92d4fa02ea

Comment by A. Jesse Jiryu Davis [ 22/Oct/18 ]

For now, the solution is to open the file stream before passing it to SecTransformCreateReadTransformWithReadStream. We're not using the suggested solution, checkResourceIsReachableAndReturnError, and we're not yet migrating from SecTransforms to "the modern SecKey APIs" since our existing code doesn't raise any deprecation warnings now.

Comment by A. Jesse Jiryu Davis [ 16/Oct/18 ]

Also from Apple:
 
I'd look at Reading From Input Streams for more guidance. But even better is to drop SecTransforms in favor of the modern SecKey APIs as recommended in Reading Files.

Comment by A. Jesse Jiryu Davis [ 10/Oct/18 ]

From Apple:

 
Is this in existing code or is new development? I ask because we don't recommend SecTransforms for new development. 
 
They're not officially deprecated at this point, but engineering efforts are all being directed at other APIs such as SecKey.
 
One easy solution is to check if the file the URL references is accessible first:
 
        NSError error = *nil;

        BOOL success = [(*__bridge* NSURL *)url checkResourceIsReachableAndReturnError:&error];

        NSLog(@"success: %d, error: %@", success, error);

Comment by A. Jesse Jiryu Davis [ 08/Oct/18 ]

I've submitted a support request to Apple. Here's the confirmation email:

 
Your request has been assigned the follow-up number listed at the top of this message. When submitting a follow-up email for this request, please include the follow-up number on the first line of your message. Here is the format you should use: Follow-up: 700966083

A Technical Support Incident (TSI) will be debited from your developer account for this inquiry. Additional TSIs are available for purchase in the Code-Level Support section of your account.

---------------------------------------------------------------------

DESCRIPTION OF PROBLEM
Hi! I wrote code like this, which works so long as the file exists:

url = CFURLCreateFromFileSystemRepresentation (
   kCFAllocatorDefault, (const UInt8 *) filename, strlen (filename), false);
read_stream = CFReadStreamCreateWithFile (kCFAllocatorDefault, url);
sec_transform = SecTransformCreateReadTransformWithReadStream (read_stream);
dataref = SecTransformExecute (sec_transform, &error);

The complete code is here:

https://github.com/mongodb/mongo-c-driver/blob/b3bdc57c2009eb918857bd9657bb8bf953a6840b/src/libmongoc/src/mongoc/mongoc-secure-transport.c#L239

If the file does not exist (the filename parameter refers to a path that does not exist on the filesystem), then this code hangs at the SecTransformExecute call. Other errors, such as a corrupt PEM file, return an error promptly.

Is there a way to receive an error quickly if the filename is wrong?

Trying to open the CFReadStream first, in order to detect errors, appears to work, but I'm concerned it's unsupported:

url = CFURLCreateFromFileSystemRepresentation (
   kCFAllocatorDefault, (const UInt8 *) filename, strlen (filename), false);
read_stream = CFReadStreamCreateWithFile (kCFAllocatorDefault, url);
if (!CFReadStreamOpen(read_stream)) {
   fprintf (stderr, "error!\n");
   return false;
}
sec_transform = SecTransformCreateReadTransformWithReadStream (read_stream);
dataref = SecTransformExecute (sec_transform, &error);

The reason I'm concerned it's unsupported is that the SecTransformCreateReadTransformWithReadStream docs for the inputStream parameter say, "The stream that is to be opened and read from when the chain executes." So it's implied that the stream should not already be opened:

https://developer.apple.com/documentation/security/1394302-sectransformcreatereadtransformw?language=objc

I request an officially supported technique to avoid a hang in SecTransformExecute when its inputs are wrong, including a bad filename. Thanks!

Generated at Wed Feb 07 21:16:27 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.