I checked your code and there is nothing wrong with that. The problem seems to be related to the format of the certificates you are trying to get with the public key.
The SecCertificateCreateWithData () function assumes that the certificate you provide is in DER format. Most of the certificates you find are base64 encoded as the well-known .pem format. I checked your code with a correctly formatted DER certificate (developer.apple.com certificate form converted to DER using openssl) and the public key is correctly extracted.
To convert a .pem certificate to DER, just use openssl in the terminal:
openssl x509 -in developer.apple.com.pem -outform der -out cert.der
After that, the certificate output file should work without problems with your code.
But you can convert the certificate directly to the application, you just need to capture the x649 base64 certificate (provided that you use certificates with the .pem encoding) and convert it to binary.
Here is an example of how you can do this:
This code will assume that the certificate is encoded in the following standard:
-----BEGIN CERTIFICATE----- < your base64 encoded certificate goes here > -----END CERTIFICATE-----
Code to convert this certificate to binary DER:
-(NSData *)getBinaryCertificateFromPemEncodedFile:(NSString *)filename andExtension:(NSString *)extension { NSString* filePath = [[NSBundle mainBundle] pathForResource:filename ofType:extension]; NSString *pemCert = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
Then a little adaptation in your perfectly functional code does the trick:
-(SecKeyRef)readPublicKeyFromCertificate:(NSData *)binaryCertificate { NSData *encodedKey = binaryCertificate; CFDataRef myCertData = (CFDataRef)CFBridgingRetain(encodedKey); SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorSystemDefault, myCertData); SecPolicyRef policy = SecPolicyCreateBasicX509(); SecTrustRef trust;
Then just name it:
NSData *data = [self getBinaryCertificateFromPemEncodedFile:@"developer" andExtension:@"pem"]; SecKeyRef key = [self readPublicKeyFromCertificate:data]; NSLog(@"%@", key);
And if your certificate is "valid", you should see:
2014-09-15 21:52:13.275 cert[15813:60b] <SecKeyRef algorithm id: 1, key type: RSAPublicKey, version: 2, block size: 2048 bits, exponent: {hex: 10001, decimal: 65537}, modulus: BE19E30F47F2D31F27D576CF007B3E615F986D14AFD0D52B825E01E90BA3E1CBB6F3A472E6AECDC28BC13D0B6E58FC497ACF61D80F274E4799602DA4F819E54ADDE2FBFA89FC4EB2172501DDED8DE0FBDDBC5550CC018C73E1FD8152C905DE850862B8D57596025DE1908D8337E95637AF0F52C4A11DA178FF737DCE09471BC0A49DAD7DB39F1BA1B693D3A12F9CA50EF388B50292C73076BF1EEE412A5CFA940E99D4CF07F17FAC87F0D0E2FC8FA3ACDDEEFCCE8AFEC407B94536FCB1E4ACF34773728D189F85EAE4347E0BF868D25C7CE89F8A29B4E6865C68F4F915DFA540549EE9333007145D367FE2852622AAD776F3E5D505A02E5155CC8646A01C1031, addr: 0x9a48200>
For testing, I used a certificate from developer.apple.com, you can check the public key in the journal and compare it.