0

I created a certificate (of p12 type) that I installed onto an iPad using Apple Configurator. I now want to access that certificate in an app I've written but I can't seem to find a source example for it. There are lots of examples on how to use certificates but I've been unable to find anything on how to import it into an app.

Can someone point me in the right direction? Thanks in advance.

* NEW *

So I tried following the tutorial here https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-SW13 using Listing 2-1 and Listing 2-2. For now I gave up on getting the certificate from the keychain and instead I load it from the main Bundle.

NSData *certData = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"myfile.com" ofType:@"pfx"]];
CFDataRef myCertData = (__bridge_retained CFDataRef)(certData); 

I'm not certain whether my loading is correct but when I debug certData is not NULL and contains bytes.

Next I modified the code in the two listings since the method signatures don't really match an Objective C method signature. Someone help me out here why Apple would show it this way? No code inside the function was modified.

- (OSStatus) extractIdentityAndTrust: (CFDataRef) inPKCS12Data withIdentity:(SecIdentityRef *) outIdentity withTrust:(SecTrustRef *) outTrust withPassword:(CFStringRef) keyPassword
{
    OSStatus securityError = errSecSuccess;
    const void *keys[] =   { kSecImportExportPassphrase };
    const void *values[] = { keyPassword };
    CFDictionaryRef optionsDictionary = NULL;

    optionsDictionary = CFDictionaryCreate(NULL, keys, values, (keyPassword ? 1 : 0), NULL, NULL);

    CFArrayRef items = NULL;
    securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);

    if (securityError == 0) {
        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust,
                                             kSecImportItemIdentity);
        CFRetain(tempIdentity);
        *outIdentity = (SecIdentityRef)tempIdentity;
        const void *tempTrust = NULL;
        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);

        CFRetain(tempTrust);
        *outTrust = (SecTrustRef)tempTrust;
    }

    if (optionsDictionary)
        CFRelease(optionsDictionary);

    if (items)
        CFRelease(items);

    return securityError;
}

Next I modified the method signature for copySummaryString. I also had to add a deference inside the function for the 'identity' variable.

- (NSString *)copySummaryString:(SecIdentityRef *) identity
{
    // Get the certificate from the identity.
    SecCertificateRef myReturnedCertificate = NULL;
    OSStatus status = SecIdentityCopyCertificate (*identity, &myReturnedCertificate);

    if (status) {
        NSLog(@"SecIdentityCopyCertificate failed.\n");
        return NULL;
    }

    CFStringRef certSummary = SecCertificateCopySubjectSummary
    (myReturnedCertificate);

    NSString* summaryString = [[NSString alloc] initWithString:(__bridge NSString *)certSummary];

    CFRelease(certSummary);

    return summaryString;
}

Finally in my calling function I created a identity and trust variable that I pass around:

[self extractIdentityAndTrust:myCertData withIdentity:identity withTrust:trust withPassword:CFSTR("supersecret")];
[self copySummaryString:identity];

When I try to run this I get a Thread 1: EXC_BAD_ACCESS(code=1, adress=0x2b) error and XCode pauses on the following line:

CFStringRef certSummary = SecCertificateCopySubjectSummary

This code doesn't reference any variable I created so I'm really surprised it's crashing here. The ultimate goal with loading this certificate is to use it for HTTPS. I hope that I'm at least on the right path here.

Przemek Lach
  • 1,348
  • 2
  • 19
  • 42

1 Answers1

1

Here is the documentation and example about finding and using of a pre-installed certificate and identity through your mobile app.

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

*NEW

I checked your update. Both you methods works like charm.

I used below source to call your methods, and was able to extract the SummaryString properly.

SecIdentityRef identity = nil;
SecTrustRef trust = nil;

NSData *certData = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"[Dev] InHouse_Certificates" ofType:@"p12"]];
CFDataRef myCertData = (__bridge_retained CFDataRef)(certData);

[self extractIdentityAndTrust:myCertData withIdentity:&identity withTrust:&trust withPassword:CFSTR("1234")];
NSString* summaryString = [self copySummaryString:&identity];
bllakjakk
  • 5,045
  • 1
  • 18
  • 28
  • I came across that documentation but was unable to get it to work. I think my problem is that I don't fully understand where the certificate is stored when loaded via Configurator: I assumed it was in the Keychain. When I try the Listing 2-5 to find my certificate the certificateRef is always null which to me means that it didn't find it. The name that I'm using for the certificate is the same as the name under my profile/Subject Name/Commmon Name. I'm either looking in the wrong place or I have the wrong name. – Przemek Lach Jan 09 '15 at 01:56
  • Your question is clear now. Actually you cannot retrieve but can access the certificate which is used to sign the application on ios device (mac is different). You can only retrieve the certificate you bundled in application or manually stored in keychain. I hope that would clear your doubt. – bllakjakk Jan 12 '15 at 05:53
  • If you want to use the certificate installed on device, you need to contact apple to get private API. Some application do that. – bllakjakk Jan 12 '15 at 06:00
  • Hi, I'm not trying to access the certificate I used to sign the application. I just want to access a certificate I uploaded using Apple Configurator. – Przemek Lach Jan 12 '15 at 18:22