Using keychain as root

Hi,

I'm writing application which use NSURLSession for https communication. It was all good until I change my app to run as root (using sudo). It is failing on the connection (SSL Error) and I suspect the fault is that it is not able to validate the server certificate. I install the relevant root certificate in the system keychain (beside login) but it did not help.

What I should do for root user to be able to use the certificates in system keychain ?

b.t.w - I'm running on macOS BigSur

Answered by DTS Engineer in 703705022

My plan is to run it as service (using sudo launchctl load).

Yeah, that’s what I suspected.

Given that, testing your program from Terminal using sudo is not a good idea. The issue here is that sudo switches the traditional BSD context to root but does not switch the security context. This mixed environment can cause all sorts of weird problems, especially when it comes to Security framework stuff like the keychain.

For more background on this, see the Execution Contents section of Technote 2083 Daemons and Agents.

The take-home message here is that, when testing a launchd daemon, always test it by loading it into the global context using sudo launchctl.

I decided to delete the root certificate and install it again.

It’s possible that the first time you set the trust settings for this root certificate, you only set them for your user and not globally.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I install the relevant root certificate in the system keychain (beside login) but it did not help.

The System keychain is, in general, available to code run using sudo. It’s hard to say what’s going on here without more context:

  • What type of credential are you dealing with here? A digital identity? An intermediate certificate? Or a trusted root certificate.

  • Are you explicitly handling TLS authentication challenges? Or relying on the NSURLSession default implementation?

  • If so, what does that code look like?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi,

I get intermediate certificate in the TLS handshake and have the issuer CA certificate installed in my system keychain.

I'm not handling the authentication challenge (no delegate) and let NSURLSession default implementation to deal with it.

I see the following error:

ATS failed system trust

Connection 1: system TLS Trust evaluation failed(-9802)

Connection 1: TLS Trust encountered error 3:-9802

Connection 1: encountered error(3:-9802)

An SSL error has occurred and a secure connection to the server cannot be made.

OK, next question: Why are you running this code using sudo? Earlier you wrote:

It was all good until I change my app to run as root

Is this an actual GUI app? Or are you using “app” in a more generic sense?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

My plan is to run it as service (using 'sudo launchctl load').

I finally realized that when running as root it complains the root certificate is not trusted (by running SecTrustEvaluateWithError).

I decided to delete the root certificate and install it again. I guess there was some bug in the keychain which show it as trusted although it was treated as not trusted.

Thanks eskimo for your help.

Accepted Answer

My plan is to run it as service (using sudo launchctl load).

Yeah, that’s what I suspected.

Given that, testing your program from Terminal using sudo is not a good idea. The issue here is that sudo switches the traditional BSD context to root but does not switch the security context. This mixed environment can cause all sorts of weird problems, especially when it comes to Security framework stuff like the keychain.

For more background on this, see the Execution Contents section of Technote 2083 Daemons and Agents.

The take-home message here is that, when testing a launchd daemon, always test it by loading it into the global context using sudo launchctl.

I decided to delete the root certificate and install it again.

It’s possible that the first time you set the trust settings for this root certificate, you only set them for your user and not globally.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Using keychain as root
 
 
Q