Sporadic errSecAuthFailed (-25293) when accessing KeyChain with SecKeychainFindGenericPassword?

StackOverflow https://stackoverflow.com/questions/1961329

  •  21-09-2019
  •  | 
  •  

Question

i'm writing an app that stores passwords on the keychain, and later obtains them with SecKeychainFindGenericPassword(). this works file 90% of the time, but every once in a while, the call to SecKeychainFindGenericPassword() will fail with errSecAuthFailed (-25293). when it does, just trying again, or restarting the app fixes it.

does anyone have an idea what could be causing this? general Google search on this error points to keychain corruption or the keychain being locked - neither of which is the case here, since subsequent calls succeed again...

Was it helpful?

Solution 3

I'm not sure this was the problem (i don't see how it could have been) but i recently changed my code to properly pass the strlen() of the cStrings, rather then the length of the NSStrings into the call. Technically this is more correct (since the string length might differ from the cString, if UTF-8 dual-byte characters are involved.

BUT, none of the usernames/passwords i tested with contained non-ASCII characters, so i don;t see how this problem could have actually affected the errors I was seeing. My new code is as follows, and i have not seen the error with it:

UInt32 length;
void *data;
const char *account = [[BC_HOST stringByAppendingFormat:@":%@", login] cStringUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Getting password from keychain.");
OSStatus s = SecKeychainFindGenericPassword (nil, 
                     strlen(BC_APPNAME), BC_APPNAME, 
                     strlen(account), account,
                     &length, &data, &keychainItem);
if (s != 0) NSLog(@"Error %d obtaining password from keychain.", s);
if (s == 0)
{
    password = [[NSString alloc] initWithBytes:data length:length encoding:NSUTF8StringEncoding];
}

OTHER TIPS

This link suggests the passphrase you entered is not correct. See Here Is it possible that sometimes you are sending a null object as a passphrase just by chance?

Alternatively, you could try out EMKeychain. I have a more up-to-date version on GitHub here: http://github.com/ctshryock/EMKeychain

You haven't shared the code around your problem, So I'll just guess your problem is not with dysfunctional keychain, but rather some coding error.

Here is a common pitfall: Since KeyChain APIs are 'C', and they only accept C-style null terminated string buffers, you'll usually need to convert your CFString/NSString objects to C buffers before handing them to the API.

Many use things like:

const char *usernameCStr = [username UTF8String];

For an NSString, or its CFString companion...

const char *CFStringGetCStringPtr(CFStringRef theString, CFStringEncoding encoding);        /* May return NULL at any time; be prepared for NULL */

Dismissing the fact these APIs may return NULL. Either because the internal buffer of the CF/NSString is non-contiguous, or not in the encoding you asked for, or otherwise not-c-compatible.

Such issue can behave in runtime exactly like what you describe.

In such cases you should catch the problem and use different API to copy the CF/NS string into a C-buffer:

Boolean CFStringGetCString(CFStringRef theString, char *buffer, CFIndex bufferSize, CFStringEncoding encoding);

or

- (BOOL)getCString:(char *)buffer maxLength:(NSUInteger)maxBufferCount encoding:(NSStringEncoding)encoding; 

I was having the same issue and in my case this turned out to be the cause: Cannot access keychain item after SMJobBless update

One possible reason that this issue can occur is if the executable making the call does not have access to the keychain item. In Keychain Access you can see a list of the apps that have permission to access the item under the Access Control tab for the item in question.

If your app is running from a different location, you will get this error. For example, I have a Privileged Helper Tool that on my dev machine I typically run through Xcode as root. The path to this executable is the path at which Xcode creates it which is a path in ~/Library/Developer/Xcode/DerivedData//myexecutable. When I run it as a user would, it is being run from /Library/PrivilegedHelperTools/myexecutable. So if the password was initially created by one version of the app and I try to read it using the other path, I will see the errSecAuthFailed error.

This isn't the only reason. Someone else mentioned the upgrade in place problem that SMJobBless has. That can also result in the same error code, but for sure I see it for both reasons - although I programmatically solved the upgrade in place issue by ordering the helper tool to move itself to a different location before I do the upgrade.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top