0

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

plaetzchen
  • 757
  • 6
  • 22

1 Answers1

2

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.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • Thank you for your help. You are right this is from an iOS application and either the documentation of 10.7 SDK or the framework is wrong. So thanks for your comment, I'll try Apple dev forums. – plaetzchen May 25 '12 at 06:33