Mac OS X: kSecPublicKeyAttrs undeclared identifier

1.1k views Asked by At

I'm trying to generate a RSA Key in my Mac OS X App, I use this code:

CFStringRef privateTag = (CFStringRef)@"com.example.privatekey";
CFStringRef publicTag = (CFStringRef)@"com.example.publickey";
int bits = 1024;
    CFMutableDictionaryRef publicAttr = CFDictionaryCreateMutable(kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFDictionaryAddValue(publicAttr, kSecAttrIsPermanent, kCFBooleanTrue);
    CFDictionaryAddValue(publicAttr, kSecAttrApplicationTag, publicTag);

    CFMutableDictionaryRef privateAttr = CFDictionaryCreateMutable(kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFDictionaryAddValue(privateAttr, kSecAttrIsPermanent, kCFBooleanTrue);
    CFDictionaryAddValue(privateAttr, kSecAttrApplicationTag, publicTag);

    CFMutableDictionaryRef keyPairAttr = CFDictionaryCreateMutable(kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFDictionaryAddValue(keyPairAttr, kSecAttrKeyType, kSecAttrKeyTypeRSA);
    CFDictionaryAddValue(keyPairAttr, kSecAttrKeySizeInBits, CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &bits));
    CFDictionaryAddValue(keyPairAttr, kSecPublicKeyAttrs, privateAttr);
    CFDictionaryAddValue(keyPairAttr, kSecPrivateKeyAttrs, publicAttr);

    status = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);

    if (status != noErr) {
        NSLog(@"something went wrong %d", (int)status);
    }else {
        NSLog(@"New key");
    }

If I try to build kSecPublicKeyAttrs is an undeclared identifier, I can't figure why. Can some one help?

Regards, Philip

1

There are 1 answers

1
abarnert On

First, you're using iOS sample code on OS X. The frameworks are similar, but not identical. But there is no OS X sample code, and the iOS sample code shows up in the OS X doc sets, so I'm not sure you can be blamed for that…

Meanwhile, while the iOS framework has public constants kSecPublicKeyAttrs and kSecPrivateKeyAttrs, if you look at the source (http://www.opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55050.2/), the OS X version has these as private constants, hidden in the framework:

/* Constants used by SecKeyGeneratePair() - in SecKey.h.  Never used in
any SecItem apis directly. */
SEC_CONST_DECL (kSecPrivateKeyAttrs, "private");
SEC_CONST_DECL (kSecPublicKeyAttrs, "public");

So, obviously you can just pass @"private" and @"public" (or create your own constants for them) and… well, I won't guarantee that it'll work, but you should at least try it.

Meanwhile, SecKeyGeneratePair's documentation says:

In addition, you can specify a number of attributes for the public and private keys individually. You can do so either by adding key-value pairs to the dictionary directly, or by adding either or both of the keys kSecPrivateKeyAttrs and kSecPublicKeyAttrs.

So either the documentation is wrong, or the framework is wrong; I'd suggest filing a bug with Apple, whether @"private" and @"public" work for you or not. And I'd suggest posting about this on the Apple devforums, where an Apple employee may notice and give you a quasi-official workaround.