user481610
user481610

Reputation: 3270

SecCertificateCreateWithData always returning null

I'm currently working from the following post. Here is the code:

    SecCertificateRef   certs    = NULL;
    SecPolicyRef        policy  = NULL;

    NSString *publicKeyString = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeJ8N8fuGShAJnniDg4yuRrxrG61ZF2T24eXSEH87jCJmLbc+MV70AgP/LC8btzSU4FFP56lBmDcmW+Prupf5gO1RXhjPIlET73t5Ny1I3ze+xaShAA9qB0c9dNb26NxVd95wCHNmQhon9qBFmTVZb0CdgscxYcDuLOGskDnATrwIDAQAB";
    NSData *publicKeyStringData = [[NSData alloc] initWithBase64EncodedString:publicKeyString options:0];


    certs = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef) publicKeyStringData);

Based on the post if the certs variable is NULL then data was in an incorrect format. I checked the above public key and it is indeed base64, so I can't see why certs would be NULL?

Upvotes: 5

Views: 9391

Answers (4)

Marek Manduch
Marek Manduch

Reputation: 2481

Certificate can have these extensions: .CER, .CRT, .DER, .PEM. And it can be encoded in two ways: DER and PEM. This apple method accepts only DER encoding.

If you have .CER or .CRT extension you have to find out if it is encoded in DER or PEM encoding. (If there is .PEM or .DER extension it is clear.)

To check the current encoding, change the extension to DER and try to read it:

  1. Rename the file (certificate.crt -> certificate.der)
  2. In terminal: openssl x509 -in certificate.der -inform der -text -noout

If you see an error it is likely PEM encoded certificate and you need to change it to DER encoded:

  1. Rename back to crt (certificate.der -> certificate.crt)
  2. In terminal: openssl x509 -in certificate.crt -outform der -out certificate.der

// source: https://support.ssl.com/Knowledgebase/Article/View/19/0/der-vs-crt-vs-cer-vs-pem-certificates-and-how-to-convert-them

Upvotes: 24

Ronak Chaniyara
Ronak Chaniyara

Reputation: 5435

If you are checking in iOS version 10 or greater, then SecCertificateCreateWithData will return nil.

something changed in the Security Framework in iOS10. Either "SecCertificateCreateWithData" is broken in iOS10 or the method has become more strict.

Looks like a bug.

You can see bug report at: https://openradar.appspot.com/28618141

Also read related gitHub post here: https://github.com/lionheart/openradar-mirror/issues/16045

Edit:

From the thread here: Why SecCertificateCreateWithData is always return nil?

Also check the documentation for the same here: SecCertificateCreateWithData

The most common reason for SecCertificateCreateWithData to return nil is that the data isn’t a valid certificate. A common problem is that folks try to pass in a PEM format certificate, whereas SecCertificateCreateWithData requires DER. If you open the certificate with a text editor, do you see Base64? Or do you see binary goo? If you see Base64, you’ll need to convert the certificate to binary (DER) form before passing to to SecCertificateCreateWithData. For a single certificate that you include in your bundle, you can just pre-convert it using Keychain Access on the Mac.

Upvotes: 5

From the documentation:

SecCertificateCreateWithData

Creates a certificate object from a DER representation of a certificate.

...

Return Value

The newly created certificate object. Call the CFRelease function to release this object when you are finished with it. Returns NULL if the data passed in the data parameter is not a valid DER-encoded X.509 certificate.

So, perhaps the NSData you're trying to use isn't in a DER format?

Upvotes: 0

Ketan Parmar
Ketan Parmar

Reputation: 27428

Try,

  NSData *data = [[NSData alloc]initWithBase64EncodedString:publicKeyString options:NSDataBase64DecodingIgnoreUnknownCharacters];


certs = SecCertificateCreateWithData(kCFAllocatorMalloc, (__bridge CFDataRef)data);

Upvotes: 0

Related Questions