Convert SecKeyRef to PEM data

I am trying to retrieve public key and private key from Mac key chain and convert it into PEM format, which will be used by another process.

I am using the following code snippet to retrieve the private key:

OSStatus status;

        NSMutableDictionary *query = [NSMutableDictionary dictionary];

        [query setObject:(id)kSecClassKey forKey:(id)kSecClass];

        [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnRef];

        [query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit];

        [query setObject:@"<label> forKey:(id)kSecAttrLabel]
          
      SecKeyRef keyRef = NULL;
    status = SecItemCopyMatching((_bridge CFDictionaryRef)query, (void *)&keyRef);

        if (status != errSecSuccess) {
            CFStringRef errorRef = SecCopyErrorMessageString(status, NULL);
            NSLog(@"%s: %@", FUNCTION, (
bridge NSString *)errorRef);
            CFRelease(errorRef);
            return ;

        }

I got a Non-Null SecKeyRef object, and no error. I verified the label previously by printing attributes.

But I cannot use this SecKeyRef for any other operations like getting public key using SecKeyCopyPublicKey, or I cannot convert into openssl format using SecKeyCopyExternalRepresentation or SecItemExport.

For SecKeyCopyExternalRepresentation, I am getting the error that "export not implemented for key" error
And with SecItemExport I am getting -25260 error.

 NSData *data = NULL;
    SecItemImportExportKeyParameters params;
    params.version = SEC
KEYIMPORTEXPORTPARAMSVERSION;

 
    params.passphrase = CFSTR("<pwd>");

    status = SecItemExport(keyRef, kSecFormatPEMSequence, kSecItemPemArmour, &params,  (__bridge CFDataRef)&data);

Could you please let me know If I am missing some other code causing the issue.



    

Replies

I was able to retrieve encrypted pem format with the below code :
Code Block
 NSData *data = NULL;
     CFDataRef exportKey;

    const char* password = "password";

    exportKey = CFDataCreate(NULL, (unsigned char*)password, strlen(password));

    SecItemImportExportKeyParameters keyParams;

    keyParams.version = SECKEYIMPORTEXPORTPARAMS_VERSION;
     keyParams.flags = 0;
     keyParams.passphrase = exportKey;
     keyParams.alertTitle = 0;
     keyParams.alertPrompt = 0;
    keyParams.accessRef = NULL;
    keyParams.keyAttributes = NULL;
    keyParams.keyUsage = NULL;
 
    status = SecItemExport(

         keyRef,
         kSecFormatWrappedPKCS8,
         kSecItemPemArmour,
         &keyParams,
         &data);