calling SecKeyCreateRandomKey while running as root

Hi,

I noticed that when running my program as root (using sudo) and calling SecKeyCreateRandomKey, the attribute for hash public key value is wrongly set.

Reading the documentation, hush public key correspond to kSecAttrApplicationLabel.

I tried setting only kSecAttrApplicationTag (or kSecAttrLabel) but it still mess up the hash key value.

Here is my code:

NSDictionary *attributes = @{(id) kSecAttrKeyType: (id)kSecAttrKeyTypeRSA,
                             (id) kSecAttrKeySizeInBits: [NSNumber numberWithInt:key_size],
                             (id) kSecAttrApplicationTag: tag_name,
                             (id) kSecPrivateKeyAttrs: @{
                               (id) kSecAttrIsPermanent:    @YES,
                               (id) kSecAttrLabel : label_name} };

private_key = SecKeyCreateRandomKey((__bridge CFDictionaryRef)attributes, &error);

I also try save it to keychain with SecItemAdd but it did not help:

NSDictionary* addquery = @{ (id)kSecValueRef: (__bridge id)private_key,
                            (id)kSecClass: (id)kSecClassKey,
                            (id)kSecAttrApplicationTag: tag };
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)addquery, NULL);

I verify the value of the public hash value using command - security dump-keychain (looking at 0x00000006 attribute).

Is that a know bug ?

Is there a way to set attributes on a private key after creating it ? for example, create it with no tag, set a tag and save it using SecItemAdd.

Thanks, Tal

Running as root using sudo puts your code in a very odd context, where it’s still running in a GUI login context but it’s not running as the owner of that GUI login context. This can cause a wide range of weird problems.

So, let’s start with the backstory: Why are you trying to manipulate the keychain while running as root using sudo?

Share and Enjoy

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

My code will actually be running as a service (LaunchDaemons), so it needs to run with sudo. This service should add/delete keys and certificate to keychain.

My code will actually be running as a service (LaunchDaemons), so it needs to run with sudo.

You have misunderstood how these parts fit together. The execution context of a launchd daemon is consistent. It runs as root in the global context and only has access to the System keychain. This is not equivalent to running the same code using sudo, which runs as root, typically in a GUI context (assuming you ran sudo from a session in Terminal), and may see the user’s login keychain but then hit weird problems trying to access it.

If your final goal it to create a launchd daemon, don’t use sudo to test your code. Rather, test your daemon in the correct context having launchd start it. I find sudo launchctl start to be super useful in this situation.

If you’re curious about the gory details here, see the Execution Contexts section of Technote 2083 Daemons and Agents. That technote is somewhat out of data, but the central message is still valid: Context really matters on macOS.

Share and Enjoy

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

calling SecKeyCreateRandomKey while running as root
 
 
Q