Eimantas
Eimantas

Reputation: 49354

Error with SecKeychainGetPath

Sometimes when trying to get a path to a keychain returned by SecKeychainCopySearchList I get error with code -25301 which from the list of errors stands for errSecBufferTooSmall. The SecCopyErrorMessageString states:

There is not enough memory available to use the specified item.

Weird thing is that it doesn't always return the error on the very same keychain reference.

Here's how I try to get the path to the keychain:

- (NSString *)getKeychainPath:(SecKeychainRef)keychain {
    char *pathName = malloc(sizeof(*pathName) * 1024);
    UInt32 pathLength;
    OSStatus errCode = SecKeychainGetPath(keychain, &pathLength, pathName);
    if (errCode != errSecSuccess) {
        NSString *errString = (NSString *)SecCopyErrorMessageString(errCode, NULL);
        DLog(@"%d: %@", errCode, errString);
    }
    NSData *d = [NSData dataWithBytes:pathName length:pathLength];
    return [[[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding] autorelease];
}

I'm interested in what buffer does the function use? I've tried outputting the pathLength variable but it's way bellow the 1K bytes. What am I doing wrong? What should I do to avoid these errors? Can they be bypassed by any way at all?

Upvotes: 3

Views: 366

Answers (1)

rob mayoff
rob mayoff

Reputation: 385970

From the SecKeychainGetPath documentation:

ioPathLength

On entry, a pointer to a variable containing the length (in bytes) of the buffer specified by pathName.
On return, the string length of pathName, not including the null termination.

You're not doing the "on input" part. You need to initialize pathLength to the size of the pathName buffer. For example:

UInt32 pathLength = 1024;
char *pathName = malloc(pathLength);

Upvotes: 4

Related Questions