Tuesday, 23 April 2019

Storing a .p12 certificate in keychain to use later

I am trying to follow the apple docs for dealing with client p12 certificates here:

https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-SW13

I have successfully loaded a .p12 cert from the file system:

- (SecIdentityRef)getClientCertificate:(NSString *) certificatePath {
    SecIdentityRef identity = nil;
    NSData *PKCS12Data = [NSData dataWithContentsOfFile:certificatePath];

    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
    CFStringRef password = CFSTR("password");
    const void *keys[] = { kSecImportExportPassphrase };
    const void *values[] = { password };
    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
    CFRelease(options);
    CFRelease(password);
    if (securityError == errSecSuccess) {
        NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
        CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
        identity = (SecIdentityRef) CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
    } else {
        NSLog(@"Error opening Certificate.");
    }

    return identity;
}

I then get the certificate for that identity:

- (CFArrayRef)getCertificate:(SecIdentityRef) identity {
    SecCertificateRef certificate = nil;

    SecIdentityCopyCertificate(identity, &certificate);
    SecCertificateRef certs[1] = { certificate };



    CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL);

    SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
    SecTrustRef myTrust;

    OSStatus status = SecTrustCreateWithCertificates(array, myPolicy, &myTrust);
    if (status == noErr) {
        NSLog(@"No Err creating certificate");
    } else {
        NSLog(@"Possible Err Creating certificate");
    }
    return array;
}

But what I really want to do is store the certificate (or the identity) in my apps keychain so I am not reading it from the file system.

A couple of questions:

  1. Which am I supposed to store? The certificate or the identity?
  2. How do I store it and retrieve it?

The link above talks about 'Getting and Using Persistent Keychain References' which is very confusing to me.

It also talks about 'Finding a Certificate In the Keychain', but it mentions using the name of the certificate to find it. I am not sure where the 'name' comes from.



from Storing a .p12 certificate in keychain to use later

No comments:

Post a Comment