inexplicable CSSMERR_CSP_OPERATION_AUTH_DENIED

I have a key for symmetric cryptography (AES, 256 bits) in my “login” keychain on macOS 10.12. The “Keychain Access” application is telling that the usage of this key is “encrypt, decrypt” and that all applications are allowed to access it without confirmation. A little Swift program of mine is able to retrieve this key from the keychain, using the function

SecItemCopyMatching
, but when it tries to use the key for encryption, in the following code, where
key
is the key and
data
some
Data
:
var optError: Unmanaged<CFError>?
let cipher = SecEncryptTransformCreate(key, &optError)
          
if let error = optError {
     throw CipherException(error.takeRetainedValue())
}
          
SecTransformSetAttribute(cipher, kSecPaddingKey, kSecPaddingPKCS7Key, &optError);
          
if let error = optError {
     throw CipherException(error.takeRetainedValue())
}

var cfData = data as CFTypeRef

SecTransformSetAttribute(cipher, kSecTransformInputAttributeName, cfData, &optError);

if let error = optError {
     throw CipherException(error.takeRetainedValue())
}

cfData = SecTransformExecute(cipher, &optError)

, it gets the error: The operation couldn’t be completed. (OSStatus error -2147416032 - CSSMERR_CSP_OPERATION_AUTH_DENIED).

How is this possible? What authorization is denied and why? Could this be a bug in macOS? I could not find any useful information about this error in the Internet, and especially not in this forum, so any help is greatly appreciated.


Maybe I should add that the key in question had been created by an earlier version of the same program. But when I try to use a new key with the same characteristics, I run into the same problem.

Post not yet marked as solved Up vote post of rx8 Down vote post of rx8
2.4k views

Answers

There’s two subsystems that can raise

CSSMERR_CSP_OPERATION_AUTH_DENIED
:
  • The keychain ACL subsystem

  • Low-level code within the keychain database implementation

Alas, I don’t enough about the latter to offer a definitive suggestion for how to differentiate between these two. So, to start, let’s look at the ACL. If you dump the keychain using this command:

$ security dump-keychain -a

what do you see for the keychain item in question?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for your attention. The output for the cryptographic key in question is the following:

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

keychain: "/Users/jakob/Library/Keychains/login.keychain-db"

version: 512

class: 0x00000011

attributes:

0x00000000 <uint32>=0x00000011

0x00000001 <blob>="Pix Cipher"

0x00000002 <blob>=<NULL>

0x00000003 <uint32>=0x00000001

0x00000004 <uint32>=0x00000000

0x00000005 <uint32>=0x00000000

0x00000006 <blob>="2015-02-14 09:17:31 +0000"

0x00000007 <blob>=<NULL>

0x00000008 <blob>=0x7B38373139316361322D306663392D313164342D383439612D3030303530326235323132327D00 "{87191ca2-0fc9-11d4-849a-000502b52122}\000"

0x00000009 <uint32>=0x80000001

0x0000000A <uint32>=0x00000100

0x0000000B <uint32>=0x00000100

0x0000000C <blob>=0x0000000000000000

0x0000000D <blob>=0x0000000000000000

0x0000000E <uint32>=0x00000000

0x0000000F <uint32>=0x00000000

0x00000010 <uint32>=0x00000001

0x00000011 <uint32>=0x00000000

0x00000012 <uint32>=0x00000001

0x00000013 <uint32>=0x00000001

0x00000014 <uint32>=0x00000000

0x00000015 <uint32>=0x00000001

0x00000016 <uint32>=0x00000001

0x00000017 <uint32>=0x00000000

0x00000018 <uint32>=0x00000000

0x00000019 <uint32>=0x00000001

0x0000001A <uint32>=0x00000001

access: 4 entries

entry 0:

authorizations (1): any

don't-require-password

description: <NULL>

applications: <null>

entry 1:

authorizations (1): integrity

don't-require-password

description: 1269a0646dc88054e0dd65a1983fb0974e178866a989abac03dbe22169ac823f

applications: <null>

entry 2:

authorizations (1): partition_id

don't-require-password

description: unsigned:

applications: <null>

entry 3:

authorizations (1): change_acl

don't-require-password

description: <NULL>

applications: <null>

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


Kind regards,

Jakob

Earlier you wrote:

Maybe I should add that the key in question had been created by an earlier version of the same program. But when I try to use a new key with the same characteristics, I run into the same problem.

Is this dump from your earlier version? Or of a newly-created key?

The reason I asked is because this part of the dump:

entry 2:
    authorizations (1): partition_id
    don't-require-password
    description: unsigned:
    applications: <null>

is a bit weird. Normally I’d expect to see the

description
line be something like this:
description: apple:

for an Apple-own program, or this:

description: teamid:SKMME9E2Y8

where

SKMME9E2Y8
is a Team ID.

A value of

unsigned:
implies that the creating app wasn’t signed at a all. Unsigned code an Apple platforms is a really bad idea for all sorts of reasons, and this is one of them.

How are you code signing your “little Swift program”?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

My little Swift application was not signed at all. With a new key, created with the now signed application, everything works as it should. Thanks alot!

With a new key, created with the now signed application, everything works as it should.

Yay! Code signing is your friend (despite what the wowsers might have you believe).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I am having an issue similar to the one rx8 described above, although my setup differs somewhat. On macOS 10.12+ I create a CSR using openSSL The private key is stashed in a private keychain, the certificate is sent to a server as part of a registration process. Upon succesful registration, the cert is returned and added to the keychain. Keychain reunites the pair as an identity. (I am able to export the identity and reimport to another keychain.) As rx8 described, when I fetch the private key (fetch the identiy, call SecIdentityCopyPrivateKey), I am not able to use the key for signature verification (via SecKeyVerifySignature) or decryption (via SecKeyCreateDecryptedData). In both cases the key passes the SecKeyIsAlgorithmSupported check. The binary that generates the key pair and manages the keychain is signed. Is creating the key pair with openssl the issue?


Here is the keychain dump of the private key:

version: 256

class: 0x00000010

attributes:

0x00000000 <uint32>=0x00000010

0x00000001 <blob>="Imported Private Key"

0x00000002 <blob>=<NULL>

0x00000003 <uint32>=0x00000001

0x00000004 <uint32>=0x00000000

0x00000005 <uint32>=0x00000000

0x00000006 <blob>=0x92A5F5BFB42DB2166383CA98E3FA827FC5D50A97 "\222\245\365\277\264-\262\026c\203\312\230\343\372\202\177\305\325\012\227"

0x00000007 <blob>=<NULL>

0x00000008 <blob>=0x7B38373139316361322D306663392D313164342D383439612D3030303530326235323132327D00 "{87191ca2-0fc9-11d4-849a-000502b52122}\000"

0x00000009 <uint32>=0x0000002A "\000\000\000*"

0x0000000A <uint32>=0x00000800

0x0000000B <uint32>=0x00000800

0x0000000C <blob>=0x0000000000000000

0x0000000D <blob>=0x0000000000000000

0x0000000E <uint32>=0x00000001

0x0000000F <uint32>=0x00000001

0x00000010 <uint32>=0x00000001

0x00000011 <uint32>=0x00000000

0x00000012 <uint32>=0x00000001

0x00000013 <uint32>=0x00000001

0x00000014 <uint32>=0x00000001

0x00000015 <uint32>=0x00000001

0x00000016 <uint32>=0x00000001

0x00000017 <uint32>=0x00000001

0x00000018 <uint32>=0x00000001

0x00000019 <uint32>=0x00000001

0x0000001A <uint32>=0x00000001

access: 3 entries

entry 0:

authorizations (6): decrypt derive export_clear export_wrapped mac sign

don't-require-password

description: Imported Private Key

applications (1):

0: /usr/local/Ivanti/Agent/bin/safestore (OK)

entry 1:

authorizations (1): encrypt

don't-require-password

description: Imported Private Key

applications: <null>

entry 2:

authorizations (1): change_acl

don't-require-password

description: Imported Private Key

applications (0):

Here is the console output when an encrypt/decrypt action is attemped:

94852

default

2018-04-04 09:53:51.028071 -0600

safestore

CSSM Exception: -2147413736 CSSMERR_DL_DATASTORE_ALREADY_EXISTS

94852

default

2018-04-04 09:53:51.029840 -0600

safestore

CSSM Exception: -2147413736 CSSMERR_DL_DATASTORE_ALREADY_EXISTS

94852

default

2018-04-04 09:53:51.031126 -0600

safestore

CSSM Exception: -2147413736 CSSMERR_DL_DATASTORE_ALREADY_EXISTS

90135

default

2018-04-04 09:53:51.089817 -0600

Keychain Access

CSSM Exception: 100000 UNIX[Undefined error: 0]

90135

default

2018-04-04 09:53:51.096217 -0600

Keychain Access

CSSM Exception: 100000 UNIX[Undefined error: 0]

94852

default

2018-04-04 09:53:51.129796 -0600

safestore

CSSM Exception: -2147413736 CSSMERR_DL_DATASTORE_ALREADY_EXISTS

90135

default

2018-04-04 09:53:51.160605 -0600

Keychain Access

CSSM Exception: 100000 UNIX[Undefined error: 0]

90135

default

2018-04-04 09:53:51.169710 -0600

Keychain Access

CSSM Exception: 100000 UNIX[Undefined error: 0]

120

default

2018-04-04 09:53:51.183954 -0600

securityd

CSSM Exception: 32 CSSM_ERRCODE_OPERATION_AUTH_DENIED

94852

default

2018-04-04 09:53:51.185042 -0600

safestore

CSSM Exception: -2147416032 CSSMERR_CSP_OPERATION_AUTH_DENIED

94852

default

2018-04-04 09:53:51.186306 -0600

safestore

CSSM Exception: -2147416032 CSSMERR_CSP_OPERATION_AUTH_DENIED

94852

default

2018-04-04 09:53:51.187453 -0600

safestore

verify result: {

"SecCertificateCopyPublicKey:publicKey" = "No error.";

"SecIdentityCopyCertificate:publicKey" = "No error.";

SecIdentityCopyPrivateKey = "No error.";

"SecItemCopyMatching:identityForName" = "No error.";

SecKeyCreateDecryptedData = "Error Domain=NSOSStatusErrorDomain Code=-25293 \"CSSM Exception: -2147416032 CSSMERR_CSP_OPERATION_AUTH_DENIED\" (errKCAuthFailed / errSecAuthFailed: / Authorization/Authentication failed.) UserInfo={NSDescription=CSSM Exception: -2147416032 CSSMERR_CSP_OPERATION_AUTH_DENIED}";

SecKeychainExists = "No error.";

SecKeychainLock = "No error.";

SecKeychainOpen = "No error.";

SecKeychainSetUserInteractionAllowed = "No error.";

SecKeychainUnlock = "No error.";

algorithmSupported = YES;

cipherText = <94e661bf 13459767 eb5066d5 7cc1a3be 68c3d019 0a15d3d5 7ad9bad2 1feebf09 ac9542ef 5ccf880a 58755735 2597957e 3ae3b9df a8ef570d 69327c66 8c16feea d7b48eb7 7a1fa1c5 23ef4778 341b6648 01ce84f3 7c43a52f 5a10eb91 09f566f3 3dcc0532 e25ee854

90135

default

2018-04-04 09:53:51.210447 -0600

Keychain Access

CSSM Exception: 100000 UNIX[Undefined error: 0]

90135

default

2018-04-04 09:53:51.216181 -0600

Keychain Access

CSSM Exception: 100000 UNIX[Undefined error: 0]